--- bip-0.8.7/src/bip.c 2011-01-15 17:29:37.000000000 +0000 +++ bip/src/bip.c 2011-03-20 19:29:35.498512003 +0000 @@ -1960,6 +1960,42 @@ void adm_away_nick(struct link_client *i } } +#define SHELL_MAX_SIZE 4096 +void adm_shell_command(struct link_client *ic, struct line *line, + unsigned int privmsg) +{ + char buf[SHELL_MAX_SIZE]; + char *argv; + int argc, i, size = 0; + FILE *pipe; + + if (!line) + return; + + argc = irc_line_count(line); + for (i = privmsg + 2; i <= argc; i++) { + argv = (i < argc) ? + (char *)irc_line_elem(line, i) : "2>&1"; + size += snprintf(&buf[size], + SHELL_MAX_SIZE - size, + "%s ", argv); + if (size >= SHELL_MAX_SIZE - 1) + goto noroom; + } +ok: + buf[size] = 0; + + if (!(pipe = popen(buf, "r"))) + return; + while (fgets(buf, SHELL_MAX_SIZE, pipe)) + bip_notify(ic, "%s", buf); + pclose(pipe); + return; +noroom: + bip_notify(ic, "shell command too big, truncated"); + goto ok; +} + void adm_bip_help(struct link_client *ic, int admin, const char *subhelp) { if (subhelp == NULL) { @@ -1992,6 +2028,7 @@ void adm_bip_help(struct link_client *ic bip_notify(ic, "/BIP AWAY_NICK # clear away nick"); bip_notify(ic, "/BIP BACKLOG [n] # backlog text of the n last " "hours"); + bip_notify(ic, "/BIP SHELL # execute shell command"); } else if (admin && strcasecmp(subhelp, "RELOAD") == 0) { bip_notify(ic, "/BIP RELOAD (admin only) :"); bip_notify(ic, " Reloads bip configuration file and apply " @@ -2265,6 +2302,13 @@ int adm_bip(bip_t *bip, struct link_clie adm_bip_delconn(bip, ic, irc_line_elem(line, privmsg + 2)); } + } else if (admin && irc_line_elem_case_equals(line, privmsg + 1, "SHELL")) { + if (irc_line_includes(line, privmsg + 2)) { + adm_shell_command(ic, line, privmsg); + } else { + bip_notify(ic, "-- SHELL command needs at " + "least one argument"); + } } else { bip_notify(ic, "Unknown command."); }