00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef lint
00021 static const char rcsid[] = "$Id: party_commands.c,v 1.28 2008-10-17 15:57:43 sven Exp $";
00022 #endif
00023
00024 #include "server.h"
00025
00026
00027 static int party_servers(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00028 {
00029 server_t *s;
00030
00031 if (server_list_len <= 0) {
00032 partymember_printf(p, _("The server list is empty."));
00033 return(BIND_RET_LOG);
00034 }
00035
00036 partymember_printf(p, _("%d server%s:"), server_list_len, (server_list_len != 1) ? "s" : "");
00037 for (s = server_list; s; s = s->next) {
00038 if (s->port) partymember_printf(p, _(" %s (port %d)%s"), s->host, s->port, s->pass ? _(" (password set)") : "");
00039 else partymember_printf(p, _(" %s (default port)%s"), s->host, s->pass ? _(" (password set)") : "");
00040 }
00041 return(BIND_RET_LOG);
00042 }
00043
00044 static void parse_server(const char *text, char **host, int *port, char **pass)
00045 {
00046 char *sep, *sport = NULL;
00047
00048 *pass = NULL;
00049 *port = 0;
00050 while (isspace(*text)) text++;
00051 *host = strdup(text);
00052 sep = strchr(*host, ' ');
00053 if (sep) {
00054 *sep++ = 0;
00055 while (isspace(*sep)) sep++;
00056 sport = sep;
00057 sep = strchr(sep, ' ');
00058 if (sep) {
00059 *sep++ = 0;
00060 while (isspace(*sep)) sep++;
00061 *pass = sep;
00062 }
00063 *port = atoi(sport);
00064 }
00065 }
00066
00067
00068 static int party_plus_server(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00069 {
00070 char *host, *pass;
00071 int port;
00072
00073 if (!text || !*text) {
00074 partymember_printf(p, _("Syntax: +server <host> [port] [pass]"));
00075 return(0);
00076 }
00077
00078 parse_server(text, &host, &port, &pass);
00079 if (!strlen(host)) {
00080 partymember_printf(p, _("Please specify a valid host."));
00081 free(host);
00082 return(0);
00083 }
00084
00085 server_add(host, port, pass);
00086 partymember_printf(p, _("Added %s/%d.\n"), host, port ? port : server_config.default_port);
00087 free(host);
00088 return(BIND_RET_LOG);
00089 }
00090
00091
00092 static int party_minus_server(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00093 {
00094 char *host, *pass;
00095 int port, i;
00096
00097 if (!text || !*text) {
00098 partymember_printf(p, _("Syntax: -server <host> [port] [pass]"));
00099 return(0);
00100 }
00101
00102 parse_server(text, &host, &port, &pass);
00103 i = server_find(host, port, pass);
00104 free(host);
00105 if (i < 0) partymember_printf(p, _("No matching servers."));
00106 else {
00107 server_del(i);
00108 partymember_printf(p, _("Deleted server %d."), i+1);
00109 }
00110 return(BIND_RET_LOG);
00111 }
00112
00113
00114 static int party_dump(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00115 {
00116 if (!text || !*text) {
00117 partymember_printf(p, _("Syntax: dump <commands>"));
00118 return(0);
00119 }
00120
00121 printserv(SERVER_NORMAL, "%s\r\n", text);
00122 return(BIND_RET_LOG);
00123 }
00124
00125
00126 static int party_jump(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00127 {
00128 char *host, *pass;
00129 int port, num;
00130
00131 if (text && *text) {
00132 parse_server(text, &host, &port, &pass);
00133 num = server_find(host, port, pass);
00134 if (num < 0) {
00135 num = server_add(host, port, pass);
00136 partymember_printf(p, _("Added %s/%d as server #%d.\n"), host, port ? port : server_config.default_port, num+1);
00137 }
00138 free(host);
00139 }
00140 else num = server_list_index+1;
00141 server_set_next(num);
00142 kill_server("changing servers");
00143 return(BIND_RET_LOG);
00144 }
00145
00146 static int party_chanmembermode(partymember_t *p, user_t *u, const char *cmd, const char *text, const char *flags, const char *mode)
00147 {
00148 char *nick, *chan;
00149 partychan_t *pchan;
00150 channel_t *ircchan;
00151
00152 egg_get_arg(text, &text, &chan);
00153
00154 if (!chan) {
00155 partymember_printf(p, "Syntax: %s [channel] <nick>", cmd);
00156 return(0);
00157 }
00158
00159 if (text && *text) nick = strdup(text);
00160 else {
00161 nick = chan;
00162 pchan = partychan_get_default(p);
00163 if (pchan) chan = strdup(pchan->name);
00164 else {
00165 partymember_printf(p, "You are not on a partyline channel! Please specify a channel: %s [channel] <nick>", cmd);
00166 free(nick);
00167 return(0);
00168 }
00169 }
00170
00171 ircchan = channel_probe(chan, 0);
00172 if (!ircchan) {
00173 partymember_printf(p, "I'm not on '%s', as far as I know!", chan);
00174 free(nick);
00175 free(chan);
00176 return(0);
00177 }
00178
00179 if (user_check_partial_flags_str(u, NULL, flags) || user_check_flags_str(u, chan, flags)) {
00180 partymember_printf(p, "Setting mode %s for %s on %s", mode, nick, ircchan->name);
00181 printserv(SERVER_NORMAL, "MODE %s %s %s", ircchan->name, mode, nick);
00182 }
00183 else {
00184 partymember_printf(p, "You need +%s to set that mode!", flags);
00185 }
00186 free(nick);
00187 free(chan);
00188 return(BIND_RET_LOG);
00189 }
00190
00191
00192 static int party_op(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00193 {
00194 return party_chanmembermode(p, u, cmd, text, "o", "+o");
00195 }
00196
00197
00198 static int party_deop(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00199 {
00200 return party_chanmembermode(p, u, cmd, text, "o", "-o");
00201 }
00202
00203
00204 static int party_halfop(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00205 {
00206 return party_chanmembermode(p, u, cmd, text, "lo", "+l");
00207 }
00208
00209
00210 static int party_dehalfop(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00211 {
00212 return party_chanmembermode(p, u, cmd, text, "lo", "-l");
00213 }
00214
00215
00216 static int party_voice(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00217 {
00218 return party_chanmembermode(p, u, cmd, text, "lo", "+v");
00219 }
00220
00221
00222 static int party_devoice(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00223 {
00224 return party_chanmembermode(p, u, cmd, text, "lo", "-v");
00225 }
00226
00227
00228 static int party_msg(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00229 {
00230 char *dest;
00231 const char *next;
00232
00233 egg_get_arg(text, &next, &dest);
00234 if (!next || !*next || !dest || !*dest) {
00235 partymember_printf(p, _("Syntax: %s <nick/chan> <message>"), cmd);
00236 if (dest) free(dest);
00237 return(0);
00238 }
00239
00240 printserv(SERVER_NORMAL, "PRIVMSG %s :%s\r\n", dest, next);
00241 partymember_printf(p, _("Msg to %1$s: %2$s"), dest, next);
00242 free(dest);
00243 return(BIND_RET_LOG);
00244 }
00245
00246
00247 static int party_act(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00248 {
00249 char *dest;
00250 const char *next;
00251
00252 egg_get_arg(text, &next, &dest);
00253 if (!next || !*next || !dest || !*dest) {
00254 partymember_printf(p, _("Syntax: act <nick/chan> <action>"));
00255 if (dest) free(dest);
00256 return(0);
00257 }
00258
00259 printserv(SERVER_NORMAL, "PRIVMSG %s :\001ACTION %s\001\r\n", dest, next);
00260 partymember_printf(p, _("Action to %1$s: %2$s"), dest, next);
00261 free(dest);
00262 return(BIND_RET_LOG);
00263 }
00264
00265 static void parse_chanset(channel_t *chan, const char *settings)
00266 {
00267 char *name, *value;
00268 char flagbuf[2] = {0, 0};
00269
00270 while (settings) {
00271 egg_get_arg(settings, &settings, &name);
00272 if (!name) break;
00273 if (*name == '+' || *name == '-') {
00274 if (*name == '+') flagbuf[0] = '1';
00275 else flagbuf[0] = '0';
00276 value = flagbuf;
00277 if (*(name+1)) channel_set(chan, flagbuf, name+1, 0, NULL);
00278 }
00279 else {
00280 egg_get_arg(settings, &settings, &value);
00281 channel_set(chan, value, name, 0, NULL);
00282 if (value) free(value);
00283 }
00284 free(name);
00285 }
00286 }
00287
00288
00289 static int party_pls_chan(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00290 {
00291 const char *settings, *chantypes;
00292 char *name, *key;
00293 channel_t *chan;
00294
00295 egg_get_arg(text, &settings, &name);
00296 if (!name) {
00297 partymember_printf(p, "Syntax: +chan <channel> [settings]");
00298 return(0);
00299 }
00300
00301 if (server_support("CHANTYPES", &chantypes) == -1) chantypes = "#&";
00302
00303 if (!strchr(chantypes, *name)) {
00304 partymember_printf(p, _("Error: '%c' is not a valid channel prefix."), *name);
00305 partymember_printf(p, _(" This server supports '%s'"), chantypes);
00306 free(name);
00307 return(0);
00308 }
00309
00310 chan = channel_lookup(name);
00311 if (chan) {
00312 if (chan->flags & CHANNEL_STATIC) {
00313 partymember_printf(p, _("Error: Channel '%s' already exists!"), name);
00314 free(name);
00315 return(0);
00316 }
00317 chan->flags |= CHANNEL_STATIC;
00318 partymember_printf(p, _("Channel '%s' has been made permanent."), name);
00319 return(BIND_RET_LOG);
00320 }
00321
00322 chan = channel_add(name);
00323 partymember_printf(p, _("Channel '%s' has been created."), name);
00324 free(name);
00325
00326 parse_chanset(chan, settings);
00327
00328 channel_get(chan, &key, "key", 0, NULL);
00329 if (key && strlen(key)) printserv(SERVER_NORMAL, "JOIN %s %s", chan->name, key);
00330 else printserv(SERVER_NORMAL, "JOIN %s", chan->name);
00331
00332 return(BIND_RET_LOG);
00333 }
00334
00335
00336 static int party_minus_chan(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00337 {
00338 while (text && isspace(*text)) text++;
00339
00340 if (!text || !*text) {
00341 partymember_printf(p, "Syntax: -chan <channel>");
00342 return(0);
00343 }
00344
00345 if (channel_remove(text)) {
00346 partymember_printf(p, "Channel not found!");
00347 return(0);
00348 }
00349
00350 partymember_printf(p, "Channel '%s' has been removed.", text);
00351 printserv(SERVER_NORMAL, "PART %s", text);
00352 return(BIND_RET_LOG);
00353 }
00354
00355 static int channel_get_modes(channel_t *chan, char *buf, int maxlen)
00356 {
00357 int i, len, l;
00358
00359 flag_to_str(&chan->mode, buf);
00360 len = strlen(buf);
00361 for (i = 0; i < chan->nargs; ++i) {
00362 if (!chan->args[i].value) continue;
00363 buf[len++] = chan->args[i].type;
00364 if (len + 1 > maxlen) {
00365 buf[len] = 0;
00366 return 1;
00367 }
00368 }
00369 buf[len] = 0;
00370 for (i = 0; i < chan->nargs; ++i) {
00371 if (!chan->args[i].value) continue;
00372 l = strlen(chan->args[i].value);
00373 if (len + 2 + l > maxlen) return 1;
00374 buf[len++] = ' ';
00375 strcpy(buf + len, chan->args[i].value);
00376 len += l;
00377 }
00378 return 0;
00379 }
00380
00381 static char channel_get_prefix(channel_member_t *m)
00382 {
00383 int i, len;
00384 char buf[256];
00385
00386 flag_to_str(&m->mode, buf);
00387 len = strlen(current_server.modeprefix);
00388 for (i = 0; i < len; ++i) {
00389 if (strchr(buf, current_server.modeprefix[i])) return current_server.whoprefix[i];
00390 }
00391 return ' ';
00392 }
00393
00394
00395 static int party_channels(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00396 {
00397 char buf[512];
00398 user_t *user;
00399 channel_t *chan;
00400 channel_member_t *m;
00401
00402 if ( !text || !*text) {
00403 if (nchannels <= 0) {
00404 partymember_printf(p, _("The channel list is empty."));
00405 return BIND_RET_LOG;
00406 }
00407
00408 for (chan = channel_head; chan; chan = chan->next) {
00409 partymember_printf(p, " %s : %d member%s", chan->name, chan->nmembers, chan->nmembers == 1 ? "" : "s");
00410 }
00411 return BIND_RET_LOG;
00412 }
00413
00414 chan = channel_probe(text, 0);
00415 if (!chan) {
00416 partymember_printf(p, "Channel not found!");
00417 return 0;
00418 }
00419
00420 if (!chan->nmembers) {
00421 partymember_printf(p, "Not in channel.");
00422 return 0;
00423 }
00424
00425 channel_get_modes(chan, buf, 512);
00426 partymember_printf(p, "Channel %s, %d member%s, mode +%s:", chan->name, chan->nmembers, chan->nmembers == 1 ? "" : "s", buf);
00427 partymember_printf(p, "Channel Topic: %s", chan->topic);
00428 partymember_printf(p, "(n = owner, m = master, o = op, d = deop, b = bot)");
00429 partymember_printf(p, " NICKNAME HANDLE JOIN IDLE USER@HOST");
00430 for (m = chan->member_head; m; m = m->next) {
00431 snprintf(buf, 512, "%s!%s", m->nick, m->uhost);
00432 user = user_lookup_by_irchost(buf);
00433 partymember_printf(p, "%c%-15s %-15s %-5s %-5s %s", channel_get_prefix(m), m->nick, user ? user->handle : "*", "N/A", "N/A", m->uhost);
00434 }
00435 partymember_printf(p, "End of channel info.");
00436 return BIND_RET_LOG;
00437 }
00438
00439
00440 static int party_chanset(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00441 {
00442 const char *settings;
00443 char *name;
00444 channel_t *chan;
00445
00446 egg_get_arg(text, &settings, &name);
00447 if (!name) {
00448 partymember_printf(p, "Syntax: %s <channel> [settings]", cmd);
00449 return(0);
00450 }
00451
00452 chan = channel_probe(name, 0);
00453 free(name);
00454 if (!chan) {
00455 partymember_printf(p, "Channel not found! Use +chan if you want to create a new channel.");
00456 return(0);
00457 }
00458
00459 parse_chanset(chan, settings);
00460 return(BIND_RET_LOG);
00461 }
00462
00463
00464 static int party_chaninfo(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00465 {
00466 channel_t *chan;
00467 char *next, *item, *value;
00468
00469 while (text && isspace(*text)) text++;
00470
00471 if (!text || !*text) {
00472 partymember_printf(p, "Syntax: %s <channel>", cmd);
00473 return(0);
00474 }
00475
00476 chan = channel_probe(text, 0);
00477 if (!chan) {
00478 partymember_printf(p, "Channel not found!");
00479 return(0);
00480 }
00481
00482 partymember_printf(p, "Information about '%s':", chan->name);
00483 if (!(chan->flags & CHANNEL_STATIC)) {
00484 partymember_printf(p, "Saved settings: none (not a static channel)");
00485 }
00486 else {
00487 next = server_config.chaninfo_items;
00488 while (next && *next) {
00489 egg_get_arg(next, &next, &item);
00490 if (!item) break;
00491 channel_get(chan, &value, item, 0, NULL);
00492 if (value) {
00493 partymember_printf(p, "%s: %s", item, value);
00494 }
00495 free(item);
00496 }
00497 }
00498 return(BIND_RET_LOG);
00499 }
00500
00501
00502 static int party_chansave(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00503 {
00504 while (text && isspace(*text)) text++;
00505
00506 channel_save(text && *text ? text : server_config.chanfile);
00507 return(BIND_RET_LOG);
00508 }
00509
00510
00511
00512 static int party_plus_mask(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00513 {
00514 return(BIND_RET_LOG);
00515 }
00516
00517
00518
00519 static int party_list_masks(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00520 {
00521 return(BIND_RET_LOG);
00522 }
00523
00524
00525
00526 static int party_minus_mask(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00527 {
00528 return(BIND_RET_LOG);
00529 }
00530
00531
00532 bind_list_t server_party_commands[] = {
00533 {"m", "servers", party_servers},
00534
00535
00536 {"o", "halfop", party_halfop},
00537 {"o", "dehalfop", party_dehalfop},
00538 {"o", "op", party_op},
00539 {"o", "deop", party_deop},
00540 {"o", "voice", party_voice},
00541 {"o", "devoice", party_devoice},
00542 {"m", "msg", party_msg},
00543 {"m", "say", party_msg},
00544 {"m", "act", party_act},
00545
00546 {"l", "+ban", party_plus_mask},
00547 {"l", "+invite", party_plus_mask},
00548 {"l", "+exempt", party_plus_mask},
00549 {"l", "+chanmask", party_plus_mask},
00550 {"l", "-ban", party_minus_mask},
00551 {"l", "-invite", party_minus_mask},
00552 {"l", "-exempt", party_minus_mask},
00553 {"l", "-chanmask", party_minus_mask},
00554 {"l", "bans", party_list_masks},
00555 {"l", "invites", party_list_masks},
00556 {"l", "exempts", party_list_masks},
00557 {"l", "chanmasks", party_list_masks},
00558 {"m", "+server", party_plus_server},
00559 {"m", "-server", party_minus_server},
00560 {"m", "dump", party_dump},
00561 {"m", "jump", party_jump},
00562 {"m", "channels", party_channels},
00563 {"n", "+chan", party_pls_chan},
00564 {"n", "-chan", party_minus_chan},
00565 {"n", "chanset", party_chanset},
00566 {"m", "chaninfo", party_chaninfo},
00567 {"n", "chansave", party_chansave},
00568 {0, 0, 0}
00569 };