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: core_party.c,v 1.55 2007-04-22 13:18:32 sven Exp $";
00022 #endif
00023
00024 #include <eggdrop/eggdrop.h>
00025 #include <unistd.h>
00026
00027 #ifdef HAVE_UNAME
00028 # include <sys/utsname.h>
00029 #endif
00030
00031 #include "core_config.h"
00032 #include "core_binds.h"
00033 #include "logfile.h"
00034 #include "terminal.h"
00035 #include "main.h"
00036
00037 static int party_help(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00038 {
00039 help_summary_t *entry;
00040 help_search_t *search;
00041 int hits = 0;
00042 xml_node_t *node, *arg, *desc, *see;
00043 char *argname, *argdesc;
00044 int optional;
00045
00046
00047 if (!text || !*text) {
00048 partymember_printf(p, "Syntax: help <command|variable|*search*>");
00049 return(0);
00050 }
00051
00052 entry = help_lookup_summary(text);
00053 if (entry) {
00054 node = help_lookup_entry(entry);
00055 partymember_printf(p, "Syntax:");
00056 partymember_printf(p, " %s", entry->syntax);
00057 partymember_printf(p, "");
00058 partymember_printf(p, "Summary:");
00059 partymember_printf(p, " %s", entry->summary);
00060 partymember_printf(p, "");
00061 xml_node_get_vars(node, "nnn", "desc.line", &desc, "args.arg", &arg, "seealso.see", &see);
00062 if (arg) {
00063 partymember_printf(p, "Arguments:");
00064 for (; arg; arg = arg->next_sibling) {
00065 xml_node_get_vars(arg, "sis", "name", &argname, "optional", &optional, "desc", &argdesc);
00066 partymember_printf(p, " %s%s - %s", argname, optional ? " (optional)" : "", argdesc);
00067 }
00068 partymember_printf(p, "");
00069 }
00070 partymember_printf(p, "Description:");
00071 for (; desc; desc = desc->next_sibling) {
00072 partymember_printf(p, " %s", xml_node_str(desc, ""));
00073 }
00074 partymember_printf(p, "");
00075 if (see) {
00076 partymember_printf(p, "See also:");
00077 for (; see; see = see->next_sibling) {
00078 partymember_printf(p, " %s", xml_node_str(see, ""));
00079 }
00080 }
00081 xml_node_delete(node);
00082 return(0);
00083 }
00084
00085
00086 if (!strchr(text, '*') && !strchr(text, '?')) {
00087 partymember_printf(p, "No help was found! Try searching with wildcards, e.g. *%s*", text);
00088 return(0);
00089 }
00090
00091 search = help_search_new(text);
00092 while ((entry = help_search_result(search))) {
00093 partymember_printf(p, "%s - %s", entry->syntax, entry->summary);
00094 hits++;
00095 }
00096 if (hits == 0) {
00097 partymember_printf(p, "No help was found! Try more wildcards...");
00098 }
00099 help_search_end(search);
00100 return(0);
00101 }
00102
00103 static int party_join(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00104 {
00105 if (!text || !*text) {
00106 partymember_printf(p, _("Syntax: join <channel>"));
00107 return(0);
00108 }
00109 partychan_join_name(text, p, 0);
00110 return(0);
00111 }
00112
00113 static int party_part(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00114 {
00115 partychan_t *chan;
00116
00117 if (!text || !*text) chan = partychan_get_default(p);
00118 else chan = partychan_lookup_name(text);
00119 partychan_part(chan, p, "parting");
00120 return(0);
00121 }
00122
00123 static int party_quit(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00124 {
00125 if (0 == strcmp (p->nick, TERMINAL_NICK)) {
00126 partymember_printf (p, "You can't leave the partyline in terminal mode.");
00127 return -1;
00128 }
00129
00130 partymember_printf(p, "Goodbye!");
00131 if (!text || !*text) partymember_delete(p, NULL, "Quit");
00132 else partymember_delete(p, NULL, text);
00133 return(0);
00134 }
00135
00136 static int party_whisper(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00137 {
00138 char *who;
00139 const char *next;
00140 botnet_entity_t src = user_entity(p);
00141 partymember_t *dest;
00142
00143 egg_get_arg(text, &next, &who);
00144 if (!who || !next || !*who || !*next) {
00145 partymember_printf(p, _("Syntax: whisper <partylineuser> <msg>"));
00146 goto done;
00147 }
00148
00149 dest = partymember_lookup(who, NULL, -1);
00150 if (!dest) {
00151 partymember_printf(p, _("No such user '%s'."), who);
00152 goto done;
00153 }
00154
00155 partymember_msg(dest, &src, next, -1);
00156 done:
00157 if (who) free(who);
00158 return(0);
00159 }
00160
00161 static void *lookup_setting(partymember_t *p, const char *path)
00162 {
00163 void *root;
00164
00165 root = config_get_root("eggdrop");
00166 root = config_exists(root, path, 0, NULL);
00167 if (!root) partymember_printf(p, _("That setting does not exist."));
00168 return(root);
00169 }
00170
00171 static int party_get(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00172 {
00173 void *root;
00174 char *str = NULL;
00175
00176 if (!text || !*text) {
00177 partymember_printf(p, _("Syntax: get <path>"));
00178 return(0);
00179 }
00180
00181 root = lookup_setting(p, text);
00182 if (!root) return(0);
00183
00184 config_get_str(&str, root, NULL);
00185 if (str) partymember_printf(p, "Current value: '%s'", str);
00186 else partymember_printf(p, _("Current value: null (unset)"));
00187 return(0);
00188 }
00189
00190 static int party_set(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00191 {
00192 void *root;
00193 char *path, *str;
00194 const char *next;
00195
00196 egg_get_arg(text, &next, &path);
00197 if (!path) {
00198 partymember_printf(p, _("Syntax: set <path> [new value]"));
00199 return(0);
00200 }
00201 if (!next) {
00202 free(path);
00203 return party_get(p, nick, u, cmd, text);
00204 }
00205
00206 root = lookup_setting(p, path);
00207 free(path);
00208 if (!root) return(0);
00209
00210 config_get_str(&str, root, NULL);
00211 partymember_printf(p, _("Old value: '%s'"), str);
00212 config_set_str(next, root, NULL);
00213 config_get_str(&str, root, NULL);
00214 if (str) partymember_printf(p, _("New value: '%s'"), str);
00215 else partymember_printf(p, _("New value: null (unset)"));
00216 return(0);
00217 }
00218
00219 static int party_unset(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00220 {
00221 void *root;
00222 char *str;
00223
00224 if (!text || !*text) {
00225 partymember_printf(p, _("Syntax: unset <path>"));
00226 return(0);
00227 }
00228
00229 root = lookup_setting(p, text);
00230 if (!root) return(0);
00231
00232 config_get_str(&str, root, NULL);
00233 if (str) partymember_printf(p, _("Old value: '%s'"), str);
00234 else partymember_printf(p, _("Old value: null (unset)"));
00235 config_set_str(NULL, root, NULL);
00236 config_get_str(&str, root, NULL);
00237 if (str) partymember_printf(p, _("New value: '%s'"), str);
00238 else partymember_printf(p, _("New value: null (unset)"));
00239 return(0);
00240 }
00241
00242 static int party_status(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00243 {
00244 #ifdef HAVE_UNAME
00245 struct utsname un;
00246 #endif
00247
00248 partymember_printf(p, _("I am %1$s, running Eggdrop %2$s."), core_config.botname, VERSION);
00249 partymember_printf(p, _("Owner: %s"), core_config.owner);
00250 if (core_config.admin) partymember_printf(p, _("Admin: %s"), core_config.admin);
00251 #ifdef HAVE_UNAME
00252 if (!uname(&un)) partymember_printf(p, _("OS: %1$s %2$s"), un.sysname, un.release);
00253 #endif
00254 partymember_printf(p, _("Help path: %s (%d entries, %d sections)"),
00255 core_config.help_path, 0, 0);
00256 partymember_printf(p, "");
00257 check_bind_status(p, text);
00258 return(0);
00259 }
00260
00261 static int party_bots(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00262 {
00263 int len, bots = 1;
00264 char obuf[201] = "";
00265 const char *botname;
00266 const botnet_bot_t *bot;
00267
00268 botname = botnet_get_name();
00269 if (strlen(botname) < 100) strcpy(obuf, botname);
00270 else sprintf(obuf, "%.96s...", botname);
00271
00272 for (bot = botnet_get_head(); bot; bot = bot->next) {
00273 ++bots;
00274 len = strlen(bot->name);
00275 if (strlen(obuf) + (len < 100 ? len : 99) + 2 > 200) {
00276 partymember_printf(p, _("Bots: %s"), obuf);
00277 if (strlen(botname) < 100) strcpy(obuf, bot->name);
00278 else sprintf(obuf, "%.96s...", bot->name);
00279 } else {
00280 if (strlen(botname) < 100) sprintf(obuf + strlen(obuf), ", %s", bot->name);
00281 else sprintf(obuf + strlen(obuf), ", %.96s...", bot->name);
00282 }
00283 }
00284 partymember_printf(p, _("Bots: %s"), obuf);
00285 partymember_printf(p, _("Total: %d"), bots);
00286 return 0;
00287 }
00288
00289 static int party_save(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00290 {
00291 putlog(LOG_MISC, "*", _("Saving user file..."));
00292 user_save(core_config.userfile);
00293 putlog(LOG_MISC, "*", _("Saving config file..."));
00294 core_config_save();
00295 return(1);
00296 }
00297
00298 static int party_newpass(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00299 {
00300 if (!text || strlen(text) < 6) {
00301 partymember_printf(p, _("Please use at least 6 characters."));
00302 return(0);
00303 }
00304 user_set_pass(p->user, text);
00305 partymember_printf(p, _("Changed password to '%s'."), text);
00306 return(0);
00307 }
00308
00309 static int intsorter(const void *left, const void *right)
00310 {
00311 return(*(int *)left - *(int *)right);
00312 }
00313
00314 static int party_who(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00315 {
00316 partymember_t *who;
00317 int *ids, len, i, width = 0;
00318
00319 partymember_printf(p, _("Partyline members:"));
00320 partymember_who(&ids, &len);
00321 qsort(ids, len, sizeof(int), intsorter);
00322 if (len > 0) {
00323 i = ids[len-1];
00324 if (!i) i++;
00325 while (i != 0) {
00326 i /= 10;
00327 width++;
00328 }
00329 }
00330 for (i = 0; i < len; i++) {
00331 who = partymember_lookup(NULL, NULL, ids[i]);
00332 partymember_printf(p, " [%*d] %s (%s@%s)", width, who->id, who->nick, who->ident, who->host);
00333 }
00334 free(ids);
00335 return(0);
00336 }
00337
00338 static int party_whois(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00339 {
00340 user_t *who;
00341 flags_t flags;
00342 char *item, *chan, *setting, *value, flagstr[64];
00343 const char *next;
00344 int i;
00345
00346 if (text && *text) who = user_lookup_by_handle(text);
00347 else who = u;
00348
00349 if (!who) {
00350 partymember_printf(p, "No such user.");
00351 return(0);
00352 }
00353
00354 next = core_config.whois_items;
00355 while (next && *next) {
00356 egg_get_arg(next, &next, &item);
00357 if (!strcasecmp(item, "handle")) {
00358 partymember_printf(p, "%s: '%s'", item, who->handle);
00359 }
00360 else if (!strcasecmp(item, "uid")) {
00361 partymember_printf(p, "%s: '%d'", item, who->uid);
00362 }
00363 else if (!strcasecmp(item, "ircmasks")) {
00364 partymember_printf(p, "%s:", item);
00365 for (i = 0; i < who->nircmasks; i++) {
00366 partymember_printf(p, " %d. '%s'", i+1, who->ircmasks[i]);
00367 }
00368 }
00369 else {
00370 if ((setting = strchr(item, '.'))) {
00371 chan = item;
00372 *setting = 0;
00373 setting++;
00374 }
00375 else {
00376 chan = NULL;
00377 setting = item;
00378 }
00379 if (!strcasecmp(setting, "flags")) {
00380 user_get_flags(who, chan, &flags);
00381 flag_to_str(&flags, flagstr);
00382 value = flagstr;
00383 }
00384 else {
00385 user_get_setting(who, chan, setting, &value);
00386 }
00387
00388 if (chan) partymember_printf(p, "%s.%s: %s", chan, setting, value);
00389 else partymember_printf(p, "%s: %s", setting, value);
00390 }
00391 free(item);
00392 }
00393 return(0);
00394 }
00395
00396 static int party_die(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00397 {
00398
00399
00400
00401
00402
00403 return core_shutdown(SHUTDOWN_GRACEFULL, nick, text);
00404 }
00405
00406 static int party_plus_user(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00407 {
00408 const char *error;
00409 user_t *newuser;
00410
00411 if (!text || !*text) {
00412 partymember_printf(p, _("Syntax: +user <handle>"));
00413 return(0);
00414 }
00415
00416 error = user_invalid_handle(text);
00417 if (error) {
00418 partymember_printf(p, _("Error: %s"), error);
00419 return(0);
00420 }
00421 newuser = user_new(text);
00422 if (newuser) partymember_printf(p, _("User '%s' created."), text);
00423 else partymember_printf(p, _("Could not create user '%s'."), text);
00424 return(0);
00425 }
00426
00427 static int party_minus_user(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00428 {
00429 user_t *who;
00430
00431 if (!text || !*text) {
00432 partymember_printf(p, _("Syntax: -user <handle>"));
00433 return(0);
00434 }
00435 who = user_lookup_by_handle(text);
00436 if (!who) partymember_printf(p, _("User '%s' not found."), text);
00437 else {
00438 partymember_printf(p, _("Deleting user '%s'."), who->handle);
00439 user_delete(who);
00440 }
00441 return(0);
00442 }
00443
00444 static int party_unlink(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00445 {
00446 char *botname;
00447 const char *reason;
00448 botnet_entity_t src = user_entity(p);
00449 botnet_bot_t *bot;
00450
00451 egg_get_arg(text, &reason, &botname);
00452 if (!botname || !*botname) {
00453 partymember_printf(p, _("Syntax: unlink <handle> [reason]"));
00454 free(botname);
00455 return 0;
00456 }
00457
00458 bot = botnet_lookup(botname);
00459 free(botname);
00460 if (!bot) {
00461 partymember_printf(p, _("Not connected to that bot."));
00462 return 0;
00463 }
00464 botnet_unlink(&src, bot, reason);
00465 return 0;
00466 }
00467
00468 static int party_link(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00469 {
00470 char *via;
00471 const char *target;
00472 botnet_bot_t *dst = NULL;
00473 botnet_entity_t src = user_entity(p);
00474
00475 if (!text || !*text) {
00476 partymember_printf(p, _("Syntax: link <handle> [via-bot]"));
00477 return 0;
00478 }
00479
00480 egg_get_arg(text, &target, &via);
00481 while (target && isspace(*target)) ++target;
00482
00483 if (target && *target) {
00484 dst = botnet_lookup(via);
00485 if (!dst && strcmp(via, botnet_get_name())) {
00486 partymember_printf(p, _("No such bot: %s."), via);
00487 free(via);
00488 return 0;
00489 }
00490 free(via);
00491 } else {
00492 target = text;
00493 free(via);
00494 }
00495 botnet_link(&src, dst, target);
00496
00497 return 0;
00498 }
00499
00500 static int party_plus_host(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00501 {
00502 user_t *who;
00503 char *target, *newhost;
00504
00505 egg_get_args(text, NULL, &target, &newhost, NULL);
00506 if (!target) {
00507 partymember_printf(p, _("Syntax: +host [handle] <host>"));
00508 return(0);
00509 }
00510 if (!newhost) {
00511 newhost = target;
00512 target = NULL;
00513 }
00514 if (target) {
00515 who = user_lookup_by_handle(target);
00516 if (!who) {
00517 partymember_printf(p, _("User '%s' not found."), target);
00518 goto done;
00519 }
00520 }
00521 else {
00522 who = u;
00523 if (!who) {
00524 partymember_printf(p, _("Only valid users can add hosts."));
00525 goto done;
00526 }
00527 }
00528 user_add_ircmask(who, newhost);
00529 partymember_printf(p, _("Added '%1$s' to user '%2$s'."), newhost, who->handle);
00530
00531 done:
00532 if (target) free(target);
00533 free(newhost);
00534
00535 return(0);
00536 }
00537
00538 static int party_minus_host(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00539 {
00540 user_t *who;
00541 char *target, *host;
00542
00543 egg_get_args(text, NULL, &target, &host, NULL);
00544 if (!target) {
00545 partymember_printf(p, _("Syntax: -host [handle] <host>"));
00546 return(0);
00547 }
00548 if (!host) {
00549 host = target;
00550 target = NULL;
00551 }
00552 if (target) {
00553 who = user_lookup_by_handle(target);
00554 if (!who) {
00555 partymember_printf(p, _("User '%s' not found."), target);
00556 goto done;
00557 }
00558 }
00559 else {
00560 who = u;
00561 if (!who) {
00562 partymember_printf(p, _("Only valid users can remove hosts."));
00563 goto done;
00564 }
00565 }
00566 if (user_del_ircmask(who, host)) {
00567 partymember_printf(p, _("Mask '%1$s' not found for user '%2$s'."), host, who->handle);
00568 }
00569 else {
00570 partymember_printf(p, _("Removed '%1$s' from user '%2$s'."), host, who->handle);
00571 }
00572
00573 done:
00574 if (target) free(target);
00575 free(host);
00576
00577 return(0);
00578 }
00579
00580
00581 static int party_chattr(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00582 {
00583 const char *next;
00584 char *who, *flags, *chan;
00585 user_t *dest;
00586 flags_t flagstruct;
00587 char flagstr[64];
00588 int n;
00589
00590 n = egg_get_args(text, &next, &who, &chan, &flags, NULL);
00591 if (!chan || !*chan) {
00592 if (who) free(who);
00593 partymember_printf(p, _("Syntax: chattr <handle> [channel] <+/-flags>"));
00594 return(0);
00595 }
00596 if (!flags || !*flags) {
00597 flags = chan;
00598 chan = NULL;
00599 }
00600 dest = user_lookup_by_handle(who);
00601 if (dest) {
00602 user_set_flags_str(dest, chan, flags);
00603 user_get_flags(dest, chan, &flagstruct);
00604 flag_to_str(&flagstruct, flagstr);
00605 partymember_printf(p, _("Flags for %s are now '%s'."), who, flagstr);
00606 }
00607 else partymember_printf(p, _("'%s' is not a valid user."), who);
00608 free(who);
00609 free(flags);
00610 if (chan) free(chan);
00611 return(0);
00612 }
00613
00614 static int party_addlog(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00615 {
00616 putlog(LOG_MISC, "*", "%s: %s", nick, text);
00617
00618 return(BIND_RET_LOG);
00619 }
00620
00621 static int party_modules(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00622 {
00623 const char **modules;
00624 int nummods, ctr;
00625
00626 nummods = module_list(&modules);
00627 partymember_printf(p, _("Loaded modules:"));
00628 for (ctr = 0; ctr < nummods; ctr++) partymember_printf(p, " %s", modules[ctr]);
00629 free(modules);
00630
00631 return(BIND_RET_LOG);
00632 }
00633
00634 static int party_loadmod(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00635 {
00636 if (!text || !*text) {
00637 partymember_printf(p, _("Syntax: loadmod <module name>"));
00638 return BIND_RET_BREAK;
00639 }
00640 switch (module_load(text)) {
00641 case 0:
00642 partymember_printf(p, _("Module '%s' loaded successfully."), text);
00643 break;
00644 case -1:
00645 partymember_printf(p, _("Module '%s' is already loaded."), text);
00646 break;
00647 case -2:
00648 partymember_printf(p, _("Module '%s' could not be loaded."), text);
00649 break;
00650 case -3:
00651 partymember_printf(p, _("Module '%s' does not have a valid initialization function. Perhaps it is not an eggdrop module?"), text);
00652 break;
00653 }
00654 return(BIND_RET_LOG);
00655 }
00656
00657 static int party_unloadmod(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00658 {
00659 if (!text || !*text) {
00660 partymember_printf(p, _("Syntax: unloadmod <module name>"));
00661 return BIND_RET_BREAK;
00662 }
00663 switch (module_unload(text, MODULE_USER)) {
00664 case 0:
00665 partymember_printf(p, _("Module '%s' unloaded successfully."), text);
00666 break;
00667 case -1:
00668 partymember_printf(p, _("Module '%s' is not loaded."), text);
00669 break;
00670 case -2:
00671 partymember_printf(p, _("Module '%s' has dependencies that are still loaded. You must unload them first."), text);
00672 break;
00673 case -3:
00674 partymember_printf(p, _("Module '%s' refuses to be unloaded by you!"), text);
00675 break;
00676 }
00677 return(BIND_RET_LOG);
00678 }
00679
00680 static int party_binds(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00681 {
00682 bind_table_t *table;
00683 bind_entry_t *entry;
00684 char flags[64];
00685
00686 partymember_printf(p, "%-16s %-16s %-16s %-10s %-5s %s", _("TABLE"), _("SYNTAX"),
00687 _("FUNCTION"), _("MASK"), _("FLAGS"), _("HITS"));
00688 for (table = bind_table_list(); table; table = table->next) {
00689 for (entry = table->entries; entry; entry = entry->next) {
00690 flag_to_str(&entry->user_flags, flags);
00691 partymember_printf(p, "%-16s %-16s %-16s %-10s %-5s %d", table->name, table->syntax,
00692 entry->function_name, entry->mask, flags, entry->nhits);
00693 }
00694 }
00695
00696 return(BIND_RET_LOG);
00697 }
00698
00699 static int party_timers(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00700 {
00701 egg_timer_t *timer;
00702 int remain, now;
00703
00704 now = timer_get_now_sec(NULL);
00705 partymember_printf(p, "ID SEC LEFT NAME");
00706 for (timer = timer_list(); timer; timer = timer->next) {
00707 remain = timer->trigger_time.sec - now;
00708 partymember_printf(p, "%-5d %-8d %s", timer->id, remain, timer->name);
00709 }
00710 return(BIND_RET_LOG);
00711 }
00712
00713 static int print_net(partymember_t *p, const char *header, int flags)
00714 {
00715 int *idx, len;
00716 int i, port, peer_port;
00717 const char *host, *peer_host;
00718 char *self_addr, *peer_addr;
00719 sockbuf_handler_t *handler;
00720
00721 sockbuf_list(&idx, &len, flags);
00722 partymember_printf(p, "%s", header);
00723 partymember_printf(p, " %3s %20s %20s %s", _("Idx"), _("Local Address"), _("Foreign Address"), _("Description"));
00724 for (i = 0; i < len; i++) {
00725 sockbuf_get_self(idx[i], &host, &port);
00726 sockbuf_get_peer(idx[i], &peer_host, &peer_port);
00727 if (!host) host = "*";
00728 if (!peer_host) peer_host = "*";
00729 sockbuf_get_handler(idx[i], &handler, NULL);
00730 if (port) self_addr = egg_mprintf("%s/%d", host, port);
00731 else self_addr = egg_mprintf("%s/*", host);
00732 if (peer_port) peer_addr = egg_mprintf("%s/%d", peer_host, peer_port);
00733 else peer_addr = egg_mprintf("%s/*", peer_host);
00734 partymember_printf(p, " %3d %20s %20s %s", idx[i], self_addr, peer_addr, handler->name);
00735 free(self_addr);
00736 free(peer_addr);
00737 }
00738 free(idx);
00739 return(0);
00740 }
00741
00742 static int party_netstats(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00743 {
00744 print_net(p, "Server Sockets", SOCKBUF_SERVER);
00745 print_net(p, "Incoming Connections", SOCKBUF_INBOUND);
00746 print_net(p, "Outgoing Connections", SOCKBUF_CLIENT);
00747 return(0);
00748 }
00749
00750 static int party_restart(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00751 {
00752 core_restart (nick);
00753
00754 return(BIND_RET_LOG);
00755 }
00756
00757
00758 static int party_chhandle(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00759 {
00760 const char *error;
00761 char *old = NULL, *newh = NULL;
00762 user_t *dest;
00763
00764 egg_get_args(text, NULL, &old, &newh, NULL);
00765 if (!old || !newh || !*old || !*newh) {
00766 if (old) free(old);
00767 if (newh) free(newh);
00768 partymember_printf(p, _("Syntax: chhandle <old_handle> <new_handle>"));
00769 return 0;
00770 }
00771
00772 dest = user_lookup_by_handle(old);
00773 if (!dest) {
00774 partymember_printf(p, _("Error: User '%s' does not exist."), old);
00775 free(old);
00776 free(newh);
00777 return 0;
00778 }
00779
00780 error = user_invalid_handle(newh);
00781 if (error) {
00782 partymember_printf(p, _("Error: %s"), error);
00783 free(old);
00784 free(newh);
00785 return 0;
00786 }
00787
00788 if (!user_change_handle(dest, newh))
00789 partymember_printf(p, _("Ok, changed."));
00790
00791 free(newh);
00792 free(old);
00793
00794 return(BIND_RET_LOG);
00795 }
00796
00797
00798 static int party_chpass(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00799 {
00800 char *user = NULL, *pass = NULL;
00801 user_t *dest;
00802
00803 egg_get_args(text, NULL, &user, &pass, NULL);
00804
00805 if (!user || !*user) {
00806 partymember_printf(p, _("Syntax: chpass <handle> [pass]"));
00807 goto chpassend;
00808 }
00809
00810 dest = user_lookup_by_handle(user);
00811 if (!dest) {
00812 partymember_printf(p, _("Error: User '%s' does not exist."), user);
00813 goto chpassend;
00814 }
00815
00816 if (pass && *pass && strlen(pass) < 6) {
00817 partymember_printf(p, _("Error: Please use at least 6 characters."));
00818 goto chpassend;
00819 }
00820
00821 if (user_set_pass(dest, pass))
00822 partymember_printf(p, _("Removed password for %s."), user);
00823 else
00824 partymember_printf(p, _("Password for %s is now '%s'."), user, pass);
00825
00826 chpassend:
00827 free(user);
00828 free(pass);
00829
00830 return(BIND_RET_LOG_COMMAND);
00831 }
00832
00833
00834 static int party_match_getbounds(const char *strstart, const char *strlimit, long *start, long *limit)
00835 {
00836 char *tmpptr;
00837
00838 if (strstart) {
00839 *start = strtol(strstart, &tmpptr, 10);
00840 if (!*strstart || *tmpptr || *start < 1) {
00841 *start = -1;
00842 return 0;
00843 }
00844
00845 if (strlimit) {
00846 *limit = strtol(strlimit, &tmpptr, 10);
00847 if (!*strlimit || *tmpptr || *limit < 1) {
00848 *limit = -1;
00849 return 0;
00850 }
00851 }
00852 else {
00853 *limit = *start;
00854 *start = 0;
00855 }
00856 }
00857 else {
00858 *limit = 20;
00859 *start = 0;
00860 }
00861
00862 return 0;
00863 }
00864
00865
00866 static int party_matchwild(partymember_t *p, const char *mask, const char *rest)
00867 {
00868 char *strstart = NULL, *strlimit = NULL;
00869 long start, limit;
00870
00871 egg_get_args(rest, NULL, &strstart, &strlimit, NULL);
00872
00873 party_match_getbounds(strstart, strlimit, &start, &limit);
00874 if (start == -1 || limit == -1)
00875 partymember_printf(p, _("Error: 'start' and 'limit' must be positive integers"));
00876 else
00877 partyline_cmd_match_ircmask(p, mask, start, limit);
00878
00879 free(strstart);
00880 free(strlimit);
00881
00882 return 0;
00883 }
00884
00885
00886 static int party_matchattr(partymember_t *p, const char *mask, const char *rest)
00887 {
00888 char *channel = NULL, *strstart = NULL, *strlimit = NULL;
00889 long start, limit;
00890 int ischan = 0;
00891
00892 egg_get_args(rest, NULL, &channel, &strstart, &strlimit, NULL);
00893
00894
00895
00896 if (channel && (*channel < '0' || *channel > '9'))
00897 ischan = 1;
00898
00899
00900 if (strlimit)
00901 party_match_getbounds(strstart, strlimit, &start, &limit);
00902 else if (strstart)
00903 party_match_getbounds(ischan?strstart:channel, ischan?NULL:strstart, &start, &limit);
00904 else if (ischan) {
00905 start = 0;
00906 limit = 20;
00907 }
00908 else
00909 party_match_getbounds(channel, NULL, &start, &limit);
00910
00911 free(strstart);
00912 free(strlimit);
00913
00914 if (start == -1 || limit == -1)
00915 partymember_printf(p, _("Error: 'start' and 'limit' must be positive integers"));
00916 else
00917 partyline_cmd_match_attr(p, mask, ischan?channel:NULL, start, limit);
00918
00919 free(channel);
00920
00921 return 0;
00922 }
00923
00924
00925
00926 static int party_match(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
00927 {
00928
00929 char *attr = NULL;
00930 const char *rest = NULL;
00931
00932
00933
00934
00935
00936 egg_get_args(text, &rest, &attr, NULL);
00937
00938 if (!attr) {
00939 partymember_printf(p, _("Syntax: match <attr> [channel] [[start] limit]"));
00940 partymember_printf(p, _(" or: match <mask> [[start] limit]"));
00941 free(attr);
00942 return 0;
00943 }
00944
00945 if (*attr == '+' || *attr == '-' || *attr == '|')
00946 party_matchattr(p, attr, rest);
00947 else if (*attr != '&')
00948 party_matchwild(p, attr, rest);
00949
00950 free(attr);
00951
00952 return(BIND_RET_LOG);
00953 }
00954
00955 static bind_list_t core_party_binds[] = {
00956 {NULL, "help", party_help},
00957 {NULL, "join", party_join},
00958 {NULL, "whisper", party_whisper},
00959 {NULL, "newpass", party_newpass},
00960 {NULL, "help", party_help},
00961 {NULL, "part", party_part},
00962 {NULL, "quit", party_quit},
00963 {NULL, "who", party_who},
00964 {NULL, "whois", party_whois},
00965 {NULL, "match", party_match},
00966 {NULL, "bots", party_bots},
00967 {"n", "addlog", party_addlog},
00968 {"n", "get", party_get},
00969 {"n", "set", party_set},
00970 {"n", "unset", party_unset},
00971 {"n", "status", party_status},
00972 {"n", "save", party_save},
00973 {"n", "die", party_die},
00974 {"n", "restart", party_restart},
00975 {"n", "+user", party_plus_user},
00976 {"n", "-user", party_minus_user},
00977 {"n", "unlink", party_unlink},
00978 {"n", "link", party_link},
00979 {"n", "chattr", party_chattr},
00980 {"n", "modules", party_modules},
00981 {"n", "loadmod", party_loadmod},
00982 {"n", "unloadmod", party_unloadmod},
00983 {"n", "binds", party_binds},
00984 {"n", "timers", party_timers},
00985 {"n", "netstats", party_netstats},
00986 {"m", "+host", party_plus_host},
00987 {"m", "-host", party_minus_host},
00988 {"t", "chhandle", party_chhandle},
00989 {"t", "chpass", party_chpass},
00990 {0}
00991 };
00992
00993 void core_party_init(void)
00994 {
00995 bind_add_list("party", core_party_binds);
00996 }
00997