/[cvs]/eggdrop1.9/src/core_party.c
ViewVC logotype

Annotation of /eggdrop1.9/src/core_party.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.52 - (hide annotations) (download) (as text)
Tue Nov 14 14:51:24 2006 UTC (12 years, 5 months ago) by sven
Branch: MAIN
Changes since 1.51: +71 -13 lines
File MIME type: text/x-chdr

Misc:
 * Bind table flag BIND_BREAKABLE now includes BIND_STACKABLE, doesn't make
   sense otherwise.
 * If the line buffer contains more than one line of text do a check if the
   index is still valid after every callback (the sockbuf might have been
   deleted).
 * Added a "Doxygen" file in the root dir. It will generate html output in
   doc/developer/html. (The dir will be created by doxygen.)

Partyline stuff:
 * Partychan join and quit functions have an extra parameter indicating if
   the event is triggered because of someone joining/quitting or botnet
   restructuring.
 * Renamed partychan_msg() to chan_msg and made it static. It can now either
   msg the whole channel or just everyone on the local bot on the channel.
 * New functions partychan_msg() (works like before) and localchan_msg() to
   send it to every local user of the chan.
 * Added stuff to the partymember struct: A pointer to the bot the user is
   on, a malloc'd string containing the full unique name in the form
   "id:nick@bot", a pointer into this string to the full name "nick@bot"
   and a pointer to the common name of the user, "nick" for local users and
   "nick@bot" for users on other bots.
 * The id of a partymember is no longer unique, only unique to the bot the
   user is on. The nick was never unique. TODO: Change the script modules
   to take care of that!
 * A partymember is now part of two double linked lists: A list of all
   partymembers and a list of all partymembers on the bot.
 * Removed the partymember_lookup_* functions. partymember_lookup() takes
   cares of all the stuff.
 * Added functions to count all users on a bot and delete all users on a bot.

Ircpartyline:
 * IRC requires nicks to be unique for everyone and useing the usual "@" in
   the "nick@bot" form doesn't work at all on IRC. Therefor the nick format
   is now: "nick*bot:id" for remote users and "nick:id" for local users.

Script stuff:
 * Added a new script parameter: 'B': A bot.
 * TODO: Change the script modules to use it!

Botnet stuff:
 * Added botnet.[ch]. Fully documented!
 * Changed the oldbotnet module to use the new botnet API. Only very basic
   stuff works atm: Bot links, unlinks, partymember joins, quits and chatter.
   But at least it doesn't matter any more if the bot is a leaf or a hub.

1 wcc 1.15 /* core_party.c: core partyline commands
2     *
3     * Copyright (C) 2003, 2004 Eggheads Development Team
4     *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * as published by the Free Software Foundation; either version 2
8     * of the License, or (at your option) any later version.
9     *
10     * This program is distributed in the hope that it will be useful,
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     * GNU General Public License for more details.
14     *
15     * You should have received a copy of the GNU General Public License
16     * along with this program; if not, write to the Free Software
17     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18     */
19 wcc 1.14
20 wcc 1.15 #ifndef lint
21 sven 1.52 static const char rcsid[] = "$Id: core_party.c,v 1.51 2006-10-01 00:48:59 sven Exp $";
22 wcc 1.15 #endif
23 wcc 1.14
24 stdarg 1.45 #include <eggdrop/eggdrop.h>
25 wcc 1.15 #include <unistd.h>
26    
27 wcc 1.14 #ifdef HAVE_UNAME
28     # include <sys/utsname.h>
29     #endif
30    
31 wcc 1.24 #include "core_config.h"
32     #include "core_binds.h"
33     #include "logfile.h"
34 wingman 1.33 #include "terminal.h" /* TERMINAL_NICK */
35 wingman 1.32 #include "main.h" /* SHUTDOWN_*, core_shutdown, core_restart */
36 wcc 1.24
37 stdarg 1.41 static int party_help(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
38     {
39     help_summary_t *entry;
40     help_search_t *search;
41     int hits = 0;
42 stdarg 1.42 xml_node_t *node, *arg, *desc, *see;
43     char *argname, *argdesc;
44     int optional;
45    
46 stdarg 1.41
47     if (!text || !*text) {
48     partymember_printf(p, "Syntax: help <command|variable|*search*>");
49     return(0);
50     }
51     /* First try to look up an exact match. */
52     entry = help_lookup_summary(text);
53     if (entry) {
54 stdarg 1.42 node = help_lookup_entry(entry);
55     partymember_printf(p, "Syntax:");
56     partymember_printf(p, " %s", entry->syntax);
57     partymember_printf(p, "");
58     partymember_printf(p, "Summary:");
59     partymember_printf(p, " %s", entry->summary);
60     partymember_printf(p, "");
61     xml_node_get_vars(node, "nnn", "desc.line", &desc, "args.arg", &arg, "seealso.see", &see);
62     if (arg) {
63     partymember_printf(p, "Arguments:");
64     for (; arg; arg = arg->next_sibling) {
65     xml_node_get_vars(arg, "sis", "name", &argname, "optional", &optional, "desc", &argdesc);
66     partymember_printf(p, " %s%s - %s", argname, optional ? " (optional)" : "", argdesc);
67     }
68     partymember_printf(p, "");
69     }
70     partymember_printf(p, "Description:");
71     for (; desc; desc = desc->next_sibling) {
72     partymember_printf(p, " %s", xml_node_str(desc, ""));
73     }
74     partymember_printf(p, "");
75     if (see) {
76     partymember_printf(p, "See also:");
77     for (; see; see = see->next_sibling) {
78     partymember_printf(p, " %s", xml_node_str(see, ""));
79     }
80     }
81     xml_node_delete(node);
82 stdarg 1.41 return(0);
83     }
84    
85     /* No, do a search. */
86 stdarg 1.42 if (!strchr(text, '*') && !strchr(text, '?')) {
87     partymember_printf(p, "No help was found! Try searching with wildcards, e.g. *%s*", text);
88     return(0);
89     }
90    
91 stdarg 1.41 search = help_search_new(text);
92     while ((entry = help_search_result(search))) {
93     partymember_printf(p, "%s - %s", entry->syntax, entry->summary);
94     hits++;
95     }
96     if (hits == 0) {
97     partymember_printf(p, "No help was found! Try more wildcards...");
98     }
99     help_search_end(search);
100     return(0);
101     }
102 stdarg 1.1
103 stdarg 1.4 static int party_join(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
104     {
105 wcc 1.12 if (!text || !*text) {
106 wcc 1.16 partymember_printf(p, _("Syntax: join <channel>"));
107 stdarg 1.4 return(0);
108     }
109 sven 1.52 partychan_join_name(text, p, 0);
110 stdarg 1.4 return(0);
111     }
112    
113     static int party_part(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
114     {
115     partychan_t *chan;
116    
117 wcc 1.12 if (!text || !*text) chan = partychan_get_default(p);
118 stdarg 1.4 else chan = partychan_lookup_name(text);
119     partychan_part(chan, p, "parting");
120     return(0);
121     }
122    
123 stdarg 1.3 static int party_quit(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
124 stdarg 1.1 {
125 wingman 1.33 if (0 == strcmp (p->nick, TERMINAL_NICK)) {
126 wingman 1.27 partymember_printf (p, "You can't leave the partyline in terminal mode.");
127     return -1;
128     }
129 darko 1.37
130 wcc 1.18 partymember_printf(p, "Goodbye!");
131 sven 1.52 if (!text || !*text) partymember_delete(p, NULL, "Quit");
132     else partymember_delete(p, NULL, text);
133 stdarg 1.1 return(0);
134     }
135    
136 wcc 1.12 static int party_whisper(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
137 stdarg 1.1 {
138 stdarg 1.13 char *who;
139     const char *next;
140     partymember_t *dest;
141    
142 stdarg 1.21 egg_get_arg(text, &next, &who);
143 stdarg 1.13 if (!who || !next || !*who || !*next) {
144 wcc 1.16 partymember_printf(p, _("Syntax: whisper <partylineuser> <msg>"));
145 stdarg 1.13 goto done;
146     }
147    
148 sven 1.52 dest = partymember_lookup(who, NULL, -1);
149 stdarg 1.13 if (!dest) {
150 wcc 1.16 partymember_printf(p, _("No such user '%s'."), who);
151 stdarg 1.13 goto done;
152     }
153    
154     partymember_msg(dest, p, next, -1);
155     done:
156     if (who) free(who);
157 stdarg 1.1 return(0);
158     }
159    
160 stdarg 1.22 static void *lookup_setting(partymember_t *p, const char *path)
161 stdarg 1.11 {
162     void *root;
163    
164     root = config_get_root("eggdrop");
165     root = config_exists(root, path, 0, NULL);
166 stdarg 1.22 if (!root) partymember_printf(p, _("That setting does not exist."));
167 stdarg 1.11 return(root);
168     }
169    
170     static int party_get(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
171     {
172     void *root;
173     char *str = NULL;
174    
175     if (!text || !*text) {
176 wcc 1.16 partymember_printf(p, _("Syntax: get <path>"));
177 stdarg 1.11 return(0);
178     }
179    
180 stdarg 1.22 root = lookup_setting(p, text);
181 stdarg 1.11 if (!root) return(0);
182    
183     config_get_str(&str, root, NULL);
184 wcc 1.24 if (str) partymember_printf(p, "Current value: '%s'", str);
185     else partymember_printf(p, _("Current value: null (unset)"));
186 stdarg 1.11 return(0);
187     }
188    
189 stdarg 1.6 static int party_set(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
190 stdarg 1.2 {
191 stdarg 1.11 void *root;
192     char *path, *str;
193     const char *next;
194    
195 stdarg 1.21 egg_get_arg(text, &next, &path);
196 stdarg 1.22 if (!path) {
197     partymember_printf(p, _("Syntax: set <path> [new value]"));
198 stdarg 1.11 return(0);
199     }
200 stdarg 1.22 if (!next) {
201     free(path);
202     return party_get(p, nick, u, cmd, text);
203     }
204 wcc 1.14
205 stdarg 1.22 root = lookup_setting(p, path);
206 stdarg 1.11 free(path);
207     if (!root) return(0);
208    
209     config_get_str(&str, root, NULL);
210 wcc 1.16 partymember_printf(p, _("Old value: '%s'"), str);
211 stdarg 1.11 config_set_str(next, root, NULL);
212     config_get_str(&str, root, NULL);
213 stdarg 1.20 if (str) partymember_printf(p, _("New value: '%s'"), str);
214     else partymember_printf(p, _("New value: null (unset)"));
215     return(0);
216     }
217    
218     static int party_unset(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
219     {
220     void *root;
221     char *str;
222    
223     if (!text || !*text) {
224     partymember_printf(p, _("Syntax: unset <path>"));
225     return(0);
226     }
227    
228 stdarg 1.22 root = lookup_setting(p, text);
229 stdarg 1.20 if (!root) return(0);
230    
231     config_get_str(&str, root, NULL);
232     if (str) partymember_printf(p, _("Old value: '%s'"), str);
233     else partymember_printf(p, _("Old value: null (unset)"));
234     config_set_str(NULL, root, NULL);
235     config_get_str(&str, root, NULL);
236     if (str) partymember_printf(p, _("New value: '%s'"), str);
237     else partymember_printf(p, _("New value: null (unset)"));
238 wcc 1.14 return(0);
239     }
240    
241     static int party_status(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
242     {
243     #ifdef HAVE_UNAME
244     struct utsname un;
245     #endif
246    
247 stdarg 1.20 partymember_printf(p, _("I am %1$s, running Eggdrop %2$s."), core_config.botname, VERSION);
248 wcc 1.16 partymember_printf(p, _("Owner: %s"), core_config.owner);
249     if (core_config.admin) partymember_printf(p, _("Admin: %s"), core_config.admin);
250 wcc 1.14 #ifdef HAVE_UNAME
251 stdarg 1.20 if (!uname(&un)) partymember_printf(p, _("OS: %1$s %2$s"), un.sysname, un.release);
252 wcc 1.14 #endif
253 stdarg 1.35 partymember_printf(p, _("Help path: %s (%d entries, %d sections)"),
254 stdarg 1.40 core_config.help_path, 0, 0);
255 stdarg 1.20 partymember_printf(p, "");
256     check_bind_status(p, text);
257 stdarg 1.2 return(0);
258     }
259    
260 sven 1.52 static int party_bots(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
261     {
262     int len, bots = 1;
263     char obuf[201] = "";
264     const char *botname;
265     const botnet_bot_t *bot;
266    
267     botname = botnet_get_name();
268     if (strlen(botname) < 100) strcpy(obuf, botname);
269     else sprintf(obuf, "%.96s...", botname);
270    
271     for (bot = botnet_get_head(); bot; bot = bot->next) {
272     ++bots;
273     len = strlen(bot->name);
274     if (strlen(obuf) + (len < 100 ? len : 99) + 2 > 200) {
275     partymember_printf(p, _("Bots: %s"), obuf);
276     if (strlen(botname) < 100) strcpy(obuf, bot->name);
277     else sprintf(obuf, "%.96s...", bot->name);
278     } else {
279     if (strlen(botname) < 100) sprintf(obuf + strlen(obuf), ", %s", bot->name);
280     else sprintf(obuf + strlen(obuf), ", %.96s...", bot->name);
281     }
282     }
283     partymember_printf(p, _("Bots: %s"), obuf);
284     partymember_printf(p, _("Total: %d"), bots);
285     return 0;
286     }
287    
288 stdarg 1.6 static int party_save(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
289 stdarg 1.2 {
290 wcc 1.16 putlog(LOG_MISC, "*", _("Saving user file..."));
291 stdarg 1.5 user_save(core_config.userfile);
292 wcc 1.16 putlog(LOG_MISC, "*", _("Saving config file..."));
293 stdarg 1.2 core_config_save();
294     return(1);
295     }
296    
297 stdarg 1.5 static int party_newpass(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
298     {
299     if (!text || strlen(text) < 6) {
300 wcc 1.16 partymember_printf(p, _("Please use at least 6 characters."));
301 stdarg 1.5 return(0);
302     }
303     user_set_pass(p->user, text);
304 wcc 1.16 partymember_printf(p, _("Changed password to '%s'."), text);
305 stdarg 1.5 return(0);
306     }
307    
308 stdarg 1.7 static int intsorter(const void *left, const void *right)
309     {
310     return(*(int *)left - *(int *)right);
311     }
312    
313     static int party_who(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
314     {
315     partymember_t *who;
316 sven 1.52 int *ids, len, i, width = 0;
317 stdarg 1.7
318 wcc 1.16 partymember_printf(p, _("Partyline members:"));
319 sven 1.52 partymember_who(&ids, &len);
320     qsort(ids, len, sizeof(int), intsorter);
321 stdarg 1.20 if (len > 0) {
322 sven 1.52 i = ids[len-1];
323 stdarg 1.20 if (!i) i++;
324     while (i != 0) {
325     i /= 10;
326     width++;
327     }
328     }
329 stdarg 1.7 for (i = 0; i < len; i++) {
330 sven 1.52 who = partymember_lookup(NULL, NULL, ids[i]);
331     partymember_printf(p, " [%*d] %s (%s@%s)", width, who->id, who->nick, who->ident, who->host);
332 stdarg 1.7 }
333 sven 1.52 free(ids);
334 stdarg 1.7 return(0);
335     }
336    
337 stdarg 1.23 static int party_whois(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
338     {
339     user_t *who;
340     flags_t flags;
341     char *item, *chan, *setting, *value, flagstr[64];
342     const char *next;
343     int i;
344    
345     if (text && *text) who = user_lookup_by_handle(text);
346     else who = u;
347    
348     if (!who) {
349     partymember_printf(p, "No such user.");
350     return(0);
351     }
352    
353     next = core_config.whois_items;
354     while (next && *next) {
355     egg_get_arg(next, &next, &item);
356     if (!strcasecmp(item, "handle")) {
357     partymember_printf(p, "%s: '%s'", item, who->handle);
358     }
359     else if (!strcasecmp(item, "uid")) {
360     partymember_printf(p, "%s: '%d'", item, who->uid);
361     }
362     else if (!strcasecmp(item, "ircmasks")) {
363     partymember_printf(p, "%s:", item);
364     for (i = 0; i < who->nircmasks; i++) {
365     partymember_printf(p, " %d. '%s'", i+1, who->ircmasks[i]);
366     }
367     }
368     else {
369 stdarg 1.25 if ((setting = strchr(item, '.'))) {
370 stdarg 1.23 chan = item;
371     *setting = 0;
372     setting++;
373     }
374     else {
375     chan = NULL;
376     setting = item;
377     }
378     if (!strcasecmp(setting, "flags")) {
379     user_get_flags(who, chan, &flags);
380     flag_to_str(&flags, flagstr);
381     value = flagstr;
382     }
383     else {
384     user_get_setting(who, chan, setting, &value);
385     }
386    
387     if (chan) partymember_printf(p, "%s.%s: %s", chan, setting, value);
388     else partymember_printf(p, "%s: %s", setting, value);
389     }
390     free(item);
391     }
392     return(0);
393     }
394    
395 stdarg 1.7 static int party_die(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
396     {
397 darko 1.37 /* XXX: should we really enable hard shutdowns?
398 wingman 1.32 if (*text && 0 == strcmp(text, "force")) {
399     return core_shutdown(SHUTDOWN_HARD, nick, text);
400     } else
401     */
402     return core_shutdown(SHUTDOWN_GRACEFULL, nick, text);
403 stdarg 1.7 }
404    
405     static int party_plus_user(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
406     {
407 sven 1.51 const char *error;
408 stdarg 1.7 user_t *newuser;
409    
410     if (!text || !*text) {
411 wcc 1.16 partymember_printf(p, _("Syntax: +user <handle>"));
412 stdarg 1.7 return(0);
413     }
414 sven 1.51
415     error = user_invalid_handle(text);
416     if (error) {
417     partymember_printf(p, _("Error: %s"), error);
418 stdarg 1.7 return(0);
419     }
420     newuser = user_new(text);
421 wcc 1.16 if (newuser) partymember_printf(p, _("User '%s' created."), text);
422     else partymember_printf(p, _("Could not create user '%s'."), text);
423 stdarg 1.7 return(0);
424     }
425    
426     static int party_minus_user(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
427     {
428     user_t *who;
429    
430     if (!text || !*text) {
431 wcc 1.16 partymember_printf(p, _("Syntax: -user <handle>"));
432 stdarg 1.7 return(0);
433     }
434     who = user_lookup_by_handle(text);
435 sven 1.52 if (!who) partymember_printf(p, _("User '%s' not found."), text);
436 stdarg 1.7 else {
437 wcc 1.16 partymember_printf(p, _("Deleting user '%s'."), who->handle);
438 stdarg 1.7 user_delete(who);
439     }
440     return(0);
441     }
442    
443 sven 1.52 static int party_link(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
444     {
445     int error;
446     user_t *who;
447    
448     if (!text || !*text) {
449     partymember_printf(p, _("Syntax: link <handle>"));
450     return 0;
451     }
452     who = user_lookup_by_handle(text);
453     if (!who) {
454     partymember_printf(p, _("User '%s' not found."), text);
455     return 0;
456     }
457     error = botnet_link(who);
458     if (!error) return 0;
459    
460     if (error == -1) {
461     partymember_printf(p, _("Error linking to '%s': User is not a bot."), who->handle);
462     } else if (error == -2) {
463     partymember_printf(p, _("Error linking to '%s': Bot type not set."), who->handle);
464     } else if (error == -3) {
465     partymember_printf(p, _("Error linking to '%s': No module loaded to link to that bot type."), who->handle);
466     }
467    
468     return 0;
469     }
470    
471 stdarg 1.7 static int party_plus_host(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
472     {
473 stdarg 1.25 user_t *who;
474     char *target, *newhost;
475    
476     egg_get_args(text, NULL, &target, &newhost, NULL);
477     if (!target) {
478     partymember_printf(p, _("Syntax: +host [handle] <host>"));
479     return(0);
480     }
481     if (!newhost) {
482     newhost = target;
483     target = NULL;
484     }
485     if (target) {
486     who = user_lookup_by_handle(target);
487     if (!who) {
488     partymember_printf(p, _("User '%s' not found."), target);
489     goto done;
490     }
491     }
492     else {
493     who = u;
494     if (!who) {
495     partymember_printf(p, _("Only valid users can add hosts."));
496     goto done;
497     }
498     }
499     user_add_ircmask(who, newhost);
500     partymember_printf(p, _("Added '%1$s' to user '%2$s'."), newhost, who->handle);
501    
502     done:
503     if (target) free(target);
504     free(newhost);
505    
506 stdarg 1.7 return(0);
507     }
508    
509 stdarg 1.9 static int party_minus_host(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
510     {
511 stdarg 1.25 user_t *who;
512     char *target, *host;
513    
514     egg_get_args(text, NULL, &target, &host, NULL);
515     if (!target) {
516     partymember_printf(p, _("Syntax: -host [handle] <host>"));
517     return(0);
518     }
519     if (!host) {
520     host = target;
521     target = NULL;
522     }
523     if (target) {
524     who = user_lookup_by_handle(target);
525     if (!who) {
526     partymember_printf(p, _("User '%s' not found."), target);
527     goto done;
528     }
529     }
530     else {
531     who = u;
532     if (!who) {
533     partymember_printf(p, _("Only valid users can remove hosts."));
534     goto done;
535     }
536     }
537     if (user_del_ircmask(who, host)) {
538     partymember_printf(p, _("Mask '%1$s' not found for user '%2$s'."), host, who->handle);
539     }
540     else {
541     partymember_printf(p, _("Removed '%1$s' from user '%2$s'."), host, who->handle);
542     }
543    
544     done:
545     if (target) free(target);
546     free(host);
547    
548 stdarg 1.9 return(0);
549     }
550    
551 stdarg 1.21 /* Syntax: chattr <user> [chan] <flags> */
552 stdarg 1.9 static int party_chattr(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
553     {
554     const char *next;
555     char *who, *flags, *chan;
556     user_t *dest;
557     flags_t flagstruct;
558     char flagstr[64];
559     int n;
560    
561 stdarg 1.21 n = egg_get_args(text, &next, &who, &chan, &flags, NULL);
562 wcc 1.14 if (!chan || !*chan) {
563 stdarg 1.10 if (who) free(who);
564 wcc 1.24 partymember_printf(p, _("Syntax: chattr <handle> [channel] <+/-flags>"));
565 stdarg 1.9 return(0);
566     }
567 wcc 1.14 if (!flags || !*flags) {
568 stdarg 1.9 flags = chan;
569     chan = NULL;
570     }
571     dest = user_lookup_by_handle(who);
572     if (dest) {
573 wingman 1.30 user_set_flags_str(dest, chan, flags);
574 stdarg 1.9 user_get_flags(dest, chan, &flagstruct);
575     flag_to_str(&flagstruct, flagstr);
576 wcc 1.16 partymember_printf(p, _("Flags for %s are now '%s'."), who, flagstr);
577 stdarg 1.9 }
578 wcc 1.24 else partymember_printf(p, _("'%s' is not a valid user."), who);
579 stdarg 1.9 free(who);
580     free(flags);
581     if (chan) free(chan);
582     return(0);
583     }
584    
585 stdarg 1.26 static int party_addlog(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
586     {
587     putlog(LOG_MISC, "*", "%s: %s", nick, text);
588 wingman 1.30
589 wcc 1.46 return(BIND_RET_LOG);
590 stdarg 1.26 }
591    
592 wcc 1.12 static int party_modules(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
593     {
594 stdarg 1.19 const char **modules;
595 wcc 1.12 int nummods, ctr;
596    
597 stdarg 1.19 nummods = module_list(&modules);
598 wcc 1.16 partymember_printf(p, _("Loaded modules:"));
599 wcc 1.12 for (ctr = 0; ctr < nummods; ctr++) partymember_printf(p, " %s", modules[ctr]);
600     free(modules);
601 wingman 1.30
602 wcc 1.46 return(BIND_RET_LOG);
603 wcc 1.12 }
604    
605 stdarg 1.26 static int party_loadmod(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
606 wcc 1.24 {
607     if (!text || !*text) {
608 stdarg 1.26 partymember_printf(p, _("Syntax: loadmod <module name>"));
609 wingman 1.30 return BIND_RET_BREAK;
610 wcc 1.24 }
611 stdarg 1.26 switch (module_load(text)) {
612     case 0:
613     partymember_printf(p, _("Module '%s' loaded successfully."), text);
614     break;
615     case -1:
616     partymember_printf(p, _("Module '%s' is already loaded."), text);
617     break;
618     case -2:
619     partymember_printf(p, _("Module '%s' could not be loaded."), text);
620     break;
621     case -3:
622     partymember_printf(p, _("Module '%s' does not have a valid initialization function. Perhaps it is not an eggdrop module?"), text);
623     break;
624     }
625 wcc 1.46 return(BIND_RET_LOG);
626 stdarg 1.26 }
627 wcc 1.24
628 stdarg 1.26 static int party_unloadmod(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
629     {
630     if (!text || !*text) {
631     partymember_printf(p, _("Syntax: unloadmod <module name>"));
632 wingman 1.30 return BIND_RET_BREAK;
633 wcc 1.24 }
634 wingman 1.34 switch (module_unload(text, MODULE_USER)) {
635 stdarg 1.26 case 0:
636     partymember_printf(p, _("Module '%s' unloaded successfully."), text);
637     break;
638     case -1:
639     partymember_printf(p, _("Module '%s' is not loaded."), text);
640     break;
641     case -2:
642     partymember_printf(p, _("Module '%s' has dependencies that are still loaded. You must unload them first."), text);
643     break;
644     case -3:
645     partymember_printf(p, _("Module '%s' refuses to be unloaded by you!"), text);
646     break;
647     }
648 wcc 1.46 return(BIND_RET_LOG);
649 wcc 1.24 }
650    
651 wingman 1.32 static int party_binds(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
652     {
653     bind_table_t *table;
654     bind_entry_t *entry;
655     char flags[64];
656    
657 stdarg 1.49 partymember_printf(p, "%-16s %-16s %-16s %-10s %-5s %s", _("TABLE"), _("SYNTAX"),
658     _("FUNCTION"), _("MASK"), _("FLAGS"), _("HITS"));
659 wingman 1.32 for (table = bind_table_list(); table; table = table->next) {
660     for (entry = table->entries; entry; entry = entry->next) {
661     flag_to_str(&entry->user_flags, flags);
662 stdarg 1.49 partymember_printf(p, "%-16s %-16s %-16s %-10s %-5s %d", table->name, table->syntax,
663     entry->function_name, entry->mask, flags, entry->nhits);
664 wingman 1.32 }
665     }
666    
667 wcc 1.46 return(BIND_RET_LOG);
668 wingman 1.32 }
669    
670 stdarg 1.43 static int party_timers(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
671     {
672     egg_timer_t *timer;
673     int remain, now;
674    
675     now = timer_get_now_sec(NULL);
676     partymember_printf(p, "ID SEC LEFT NAME");
677     for (timer = timer_list(); timer; timer = timer->next) {
678     remain = timer->trigger_time.sec - now;
679     partymember_printf(p, "%-5d %-8d %s", timer->id, remain, timer->name);
680     }
681     return(BIND_RET_LOG);
682     }
683    
684 stdarg 1.44 static int print_net(partymember_t *p, const char *header, int flags)
685     {
686     int *idx, len;
687     int i, port, peer_port;
688     const char *host, *peer_host;
689     char *self_addr, *peer_addr;
690     sockbuf_handler_t *handler;
691    
692     sockbuf_list(&idx, &len, flags);
693     partymember_printf(p, "%s", header);
694     partymember_printf(p, " %3s %20s %20s %s", _("Idx"), _("Local Address"), _("Foreign Address"), _("Description"));
695     for (i = 0; i < len; i++) {
696     sockbuf_get_self(idx[i], &host, &port);
697     sockbuf_get_peer(idx[i], &peer_host, &peer_port);
698     if (!host) host = "*";
699     if (!peer_host) peer_host = "*";
700     sockbuf_get_handler(idx[i], &handler, NULL);
701     if (port) self_addr = egg_mprintf("%s/%d", host, port);
702     else self_addr = egg_mprintf("%s/*", host);
703     if (peer_port) peer_addr = egg_mprintf("%s/%d", peer_host, peer_port);
704     else peer_addr = egg_mprintf("%s/*", peer_host);
705     partymember_printf(p, " %3d %20s %20s %s", idx[i], self_addr, peer_addr, handler->name);
706     free(self_addr);
707     free(peer_addr);
708     }
709     free(idx);
710     return(0);
711     }
712    
713     static int party_netstats(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
714     {
715     print_net(p, "Server Sockets", SOCKBUF_SERVER);
716     print_net(p, "Incoming Connections", SOCKBUF_INBOUND);
717     print_net(p, "Outgoing Connections", SOCKBUF_CLIENT);
718     return(0);
719     }
720    
721 wingman 1.33 static int party_restart(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
722     {
723     core_restart (nick);
724 darko 1.37
725 wcc 1.46 return(BIND_RET_LOG);
726 wingman 1.33 }
727    
728 darko 1.36 /* Syntax: chhandle <old_handle> <new_handle> */
729     static int party_chhandle(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
730     {
731 sven 1.51 const char *error;
732 stdarg 1.40 char *old = NULL, *newh = NULL;
733 darko 1.36 user_t *dest;
734    
735 stdarg 1.40 egg_get_args(text, NULL, &old, &newh, NULL);
736     if (!old || !newh || !*old || !*newh) {
737     if (old) free(old);
738     if (newh) free(newh);
739 darko 1.36 partymember_printf(p, _("Syntax: chhandle <old_handle> <new_handle>"));
740 sven 1.50 return 0;
741 darko 1.36 }
742    
743     dest = user_lookup_by_handle(old);
744     if (!dest) {
745 sven 1.50 partymember_printf(p, _("Error: User '%s' does not exist."), old);
746 stdarg 1.40 free(old);
747     free(newh);
748 sven 1.50 return 0;
749 darko 1.36 }
750    
751 sven 1.51 error = user_invalid_handle(newh);
752     if (error) {
753     partymember_printf(p, _("Error: %s"), error);
754 stdarg 1.40 free(old);
755     free(newh);
756     return 0;
757 darko 1.36 }
758    
759 stdarg 1.40 if (!user_change_handle(dest, newh))
760 darko 1.36 partymember_printf(p, _("Ok, changed."));
761 darko 1.39
762 stdarg 1.40 free(newh);
763 darko 1.39 free(old);
764    
765 wcc 1.46 return(BIND_RET_LOG);
766 darko 1.36 }
767    
768 darko 1.39 /* Syntax: chpass <handle> [new_pass] */
769 darko 1.37 static int party_chpass(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
770     {
771     char *user = NULL, *pass = NULL;
772     user_t *dest;
773    
774     egg_get_args(text, NULL, &user, &pass, NULL);
775    
776 darko 1.38 if (!user || !*user) {
777     partymember_printf(p, _("Syntax: chpass <handle> [pass]"));
778 darko 1.39 goto chpassend;
779 darko 1.37 }
780    
781     dest = user_lookup_by_handle(user);
782     if (!dest) {
783     partymember_printf(p, _("Error: User '%s' does not exist."), user);
784 darko 1.39 goto chpassend;
785 darko 1.37 }
786    
787 darko 1.38 if (pass && *pass && strlen(pass) < 6) {
788 darko 1.37 partymember_printf(p, _("Error: Please use at least 6 characters."));
789 darko 1.39 goto chpassend;
790 darko 1.37 }
791    
792 darko 1.38 if (user_set_pass(dest, pass))
793     partymember_printf(p, _("Removed password for %s."), user);
794     else
795     partymember_printf(p, _("Password for %s is now '%s'."), user, pass);
796 darko 1.39
797     chpassend:
798     free(user);
799     free(pass);
800    
801 lordares 1.47 return(BIND_RET_LOG_COMMAND);
802 darko 1.39 }
803    
804     /* Makes sure 'start' and 'limit' arguments for .match are reasonable, or else sets them -1 */
805     static int party_match_getbounds(const char *strstart, const char *strlimit, long *start, long *limit)
806     {
807     char *tmpptr;
808    
809     if (strstart) {
810     *start = strtol(strstart, &tmpptr, 10);
811     if (!*strstart || *tmpptr || *start < 1) { /* Invalid input*/
812     *start = -1;
813     return 0;
814     }
815    
816     if (strlimit) { /* 'start' was really a start and this is now 'limit' */
817     *limit = strtol(strlimit, &tmpptr, 10);
818     if (!*strlimit || *tmpptr || *limit < 1) { /* Invalid input*/
819     *limit = -1;
820     return 0;
821     }
822     }
823     else { /* Ah, no, the only argument specified was the 'limit' */
824     *limit = *start;
825     *start = 0;
826     }
827     }
828     else {
829     *limit = 20;
830     *start = 0;
831     }
832    
833     return 0;
834     }
835    
836     /* Handles case where .match was given mask to match against */
837     static int party_matchwild(partymember_t *p, const char *mask, const char *rest)
838     {
839     char *strstart = NULL, *strlimit = NULL;
840     long start, limit;
841    
842     egg_get_args(rest, NULL, &strstart, &strlimit, NULL);
843    
844     party_match_getbounds(strstart, strlimit, &start, &limit);
845     if (start == -1 || limit == -1)
846     partymember_printf(p, _("Error: 'start' and 'limit' must be positive integers"));
847     else
848     partyline_cmd_match_ircmask(p, mask, start, limit);
849    
850     free(strstart);
851     free(strlimit);
852    
853 darko 1.37 return 0;
854     }
855    
856 darko 1.39 /* Handles case where .match was given attributes to match against */
857     static int party_matchattr(partymember_t *p, const char *mask, const char *rest)
858     {
859     char *channel = NULL, *strstart = NULL, *strlimit = NULL;
860     long start, limit;
861     int ischan = 0;
862    
863     egg_get_args(rest, NULL, &channel, &strstart, &strlimit, NULL);
864    
865     /* This is probably the easiest way to conclude if content of 'channel'
866     is *NOT* a number, and thus it is a candidate for a valid channel name */
867     if (channel && (*channel < '0' || *channel > '9'))
868     ischan = 1;
869    
870    
871     if (strlimit) /* .match <flags> <channel> <start> <limit> */
872     party_match_getbounds(strstart, strlimit, &start, &limit);
873     else if (strstart) /* .match <flags> <channel|start> <limit> */
874     party_match_getbounds(ischan?strstart:channel, ischan?NULL:strstart, &start, &limit);
875     else if (ischan) { /* .match <flags> <channel> */
876     start = 0;
877     limit = 20;
878     }
879     else /* .match <flags> [limit] */
880     party_match_getbounds(channel, NULL, &start, &limit);
881    
882     free(strstart);
883     free(strlimit);
884    
885     if (start == -1 || limit == -1)
886     partymember_printf(p, _("Error: 'start' and 'limit' must be positive integers"));
887     else
888     partyline_cmd_match_attr(p, mask, ischan?channel:NULL, start, limit);
889    
890     free(channel);
891    
892     return 0;
893     }
894    
895     /* match <attr> [channel] [[start] limit] */
896     /* match <mask> [[start] limit] */
897     static int party_match(partymember_t *p, const char *nick, user_t *u, const char *cmd, const char *text)
898     {
899    
900     char *attr = NULL;
901     const char *rest = NULL;
902    
903     /* FIXME - Check if user is allowed to see results.. if !chan && !glob_master && -> error
904     I have left it available to everyone because 'whois' was that way too.
905     We should update both or neither */
906    
907     egg_get_args(text, &rest, &attr, NULL);
908    
909     if (!attr) {
910     partymember_printf(p, _("Syntax: match <attr> [channel] [[start] limit]"));
911     partymember_printf(p, _(" or: match <mask> [[start] limit]"));
912     free(attr);
913     return 0;
914     }
915    
916     if (*attr == '+' || *attr == '-' || *attr == '|')
917     party_matchattr(p, attr, rest);
918     else if (*attr != '&')
919     party_matchwild(p, attr, rest);
920    
921     free(attr);
922    
923 wcc 1.46 return(BIND_RET_LOG);
924 darko 1.39 }
925    
926     static bind_list_t core_party_binds[] = { /* Old flags requirement */
927 stdarg 1.41 {NULL, "help", party_help},
928 wingman 1.29 {NULL, "join", party_join}, /* DDD */
929     {NULL, "whisper", party_whisper}, /* DDD */
930 darko 1.39 {NULL, "newpass", party_newpass}, /* DDC */ /* -|- */
931     {NULL, "help", party_help}, /* DDC */ /* -|- */
932 wingman 1.29 {NULL, "part", party_part}, /* DDD */
933 darko 1.39 {NULL, "quit", party_quit}, /* DDD */ /* -|- */
934 wingman 1.29 {NULL, "who", party_who}, /* DDD */
935 darko 1.39 {NULL, "whois", party_whois}, /* DDC */ /* ot|o */
936     {NULL, "match", party_match}, /* DDC */ /* ot|o */
937 sven 1.52 {NULL, "bots", party_bots}, /* DDD */ /* -|- */
938 darko 1.39 {"n", "addlog", party_addlog}, /* DDD */ /* ot|o */
939 wingman 1.30 {"n", "get", party_get}, /* DDC */
940     {"n", "set", party_set}, /* DDC */
941     {"n", "unset", party_unset}, /* DDC */
942 darko 1.39 {"n", "status", party_status}, /* DDC */ /* m|m */
943     {"n", "save", party_save}, /* DDD */ /* m|m */
944     {"n", "die", party_die}, /* DDD */ /* n|- */
945     {"n", "restart", party_restart}, /* DDD */ /* m|- */
946     {"n", "+user", party_plus_user}, /* DDC */ /* m|- */
947     {"n", "-user", party_minus_user}, /* DDC */ /* m|- */
948 sven 1.52 {"n", "link", party_link}, /* DDD */ /* t|- */
949 darko 1.39 {"n", "chattr", party_chattr}, /* DDC */ /* m|m */
950     {"n", "modules", party_modules}, /* DDD */ /* n|- */
951     {"n", "loadmod", party_loadmod}, /* DDD */ /* n|- */
952     {"n", "unloadmod", party_unloadmod}, /* DDD */ /* n|- */
953     {"n", "binds", party_binds}, /* DDD */ /* m|- */
954 stdarg 1.43 {"n", "timers", party_timers},
955 stdarg 1.44 {"n", "netstats", party_netstats},
956 darko 1.39 {"m", "+host", party_plus_host}, /* DDC */ /* t|m */
957     {"m", "-host", party_minus_host}, /* DDC */ /* -|- */
958     {"t", "chhandle", party_chhandle}, /* DDC */ /* t|- */
959     {"t", "chpass", party_chpass}, /* DDC */ /* t|- */
960 stdarg 1.1 {0}
961     };
962    
963 wingman 1.27 void core_party_init(void)
964 stdarg 1.1 {
965     bind_add_list("party", core_party_binds);
966     }
967 darko 1.39

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23