/[cvs]/eggdrop1.8/src/tcluser.c
ViewVC logotype

Annotation of /eggdrop1.8/src/tcluser.c

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


Revision 1.2 - (hide annotations) (download) (as text)
Thu Aug 5 18:12:05 2010 UTC (9 years, 11 months ago) by pseudo
Branch: MAIN
CVS Tags: HEAD
Branch point for: gettext
Changes since 1.1: +9 -1 lines
File MIME type: text/x-chdr
Added new, full IPv6 support to eggdrop.

1 simple 1.1 /*
2     * tcluser.c -- handles:
3     * Tcl stubs for the user-record-oriented commands
4     *
5 pseudo 1.2 * $Id: tcluser.c,v 1.2 2010/08/05 18:12:05 pseudo Exp $
6 simple 1.1 */
7     /*
8     * Copyright (C) 1997 Robey Pointer
9     * Copyright (C) 1999 - 2010 Eggheads Development Team
10     *
11     * This program is free software; you can redistribute it and/or
12     * modify it under the terms of the GNU General Public License
13     * as published by the Free Software Foundation; either version 2
14     * of the License, or (at your option) any later version.
15     *
16     * This program is distributed in the hope that it will be useful,
17     * but WITHOUT ANY WARRANTY; without even the implied warranty of
18     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19     * GNU General Public License for more details.
20     *
21     * You should have received a copy of the GNU General Public License
22     * along with this program; if not, write to the Free Software
23     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24     */
25    
26     #include "main.h"
27     #include "users.h"
28     #include "chan.h"
29     #include "tandem.h"
30     #include "modules.h"
31    
32     extern Tcl_Interp *interp;
33     extern struct userrec *userlist;
34     extern int default_flags, dcc_total, ignore_time;
35     extern struct dcc_t *dcc;
36     extern char botnetnick[];
37     extern time_t now;
38    
39    
40     static int tcl_countusers STDVAR
41     {
42     BADARGS(1, 1, "");
43    
44     Tcl_AppendResult(irp, int_to_base10(count_users(userlist)), NULL);
45     return TCL_OK;
46     }
47    
48     static int tcl_validuser STDVAR
49     {
50     BADARGS(2, 2, " handle");
51    
52     Tcl_AppendResult(irp, get_user_by_handle(userlist, argv[1]) ? "1" : "0",
53     NULL);
54     return TCL_OK;
55     }
56    
57     static int tcl_finduser STDVAR
58     {
59     struct userrec *u;
60    
61     BADARGS(2, 2, " nick!user@host");
62    
63     u = get_user_by_host(argv[1]);
64     Tcl_AppendResult(irp, u ? u->handle : "*", NULL);
65     return TCL_OK;
66     }
67    
68     static int tcl_passwdOk STDVAR
69     {
70     struct userrec *u;
71    
72     BADARGS(3, 3, " handle passwd");
73    
74     Tcl_AppendResult(irp, ((u = get_user_by_handle(userlist, argv[1])) &&
75     u_pass_match(u, argv[2])) ? "1" : "0", NULL);
76     return TCL_OK;
77     }
78    
79     static int tcl_chattr STDVAR
80     {
81     int of, ocf = 0;
82     char *chan, *chg, work[100];
83     struct flag_record pls, mns, user;
84     struct userrec *u;
85    
86     BADARGS(2, 4, " handle ?changes? ?channel?");
87    
88     if ((argv[1][0] == '*') || !(u = get_user_by_handle(userlist, argv[1]))) {
89     Tcl_AppendResult(irp, "*", NULL);
90     return TCL_OK;
91     }
92     if (argc == 4) {
93     user.match = FR_GLOBAL | FR_CHAN;
94     chan = argv[3];
95     chg = argv[2];
96     } else if (argc == 3 && argv[2][0]) {
97     int ischan = (findchan_by_dname(argv[2]) != NULL);
98    
99     if (strchr(CHANMETA, argv[2][0]) && !ischan && argv[2][0] != '+' &&
100     argv[2][0] != '-') {
101     Tcl_AppendResult(irp, "no such channel", NULL);
102     return TCL_ERROR;
103     } else if (ischan) {
104     /* Channel exists */
105     user.match = FR_GLOBAL | FR_CHAN;
106     chan = argv[2];
107     chg = NULL;
108     } else {
109     /* 3rd possibility... channel doesnt exist, does start with a +.
110     * In this case we assume the string is flags.
111     */
112     user.match = FR_GLOBAL;
113     chan = NULL;
114     chg = argv[2];
115     }
116     } else {
117     user.match = FR_GLOBAL;
118     chan = NULL;
119     chg = NULL;
120     }
121     if (chan && !findchan_by_dname(chan)) {
122     Tcl_AppendResult(irp, "no such channel", NULL);
123     return TCL_ERROR;
124     }
125     /* Retrieve current flags */
126     get_user_flagrec(u, &user, chan);
127     /* Make changes */
128     if (chg) {
129     of = user.global;
130     pls.match = user.match;
131     break_down_flags(chg, &pls, &mns);
132     /* No-one can change these flags on-the-fly */
133     pls.global &=~(USER_BOT);
134     mns.global &=~(USER_BOT);
135    
136     if (chan) {
137     pls.chan &= ~(BOT_SHARE);
138     mns.chan &= ~(BOT_SHARE);
139     }
140     user.global = sanity_check((user.global |pls.global) &~mns.global);
141    
142     user.udef_global = (user.udef_global | pls.udef_global)
143     & ~mns.udef_global;
144     if (chan) {
145     ocf = user.chan;
146     user.chan = chan_sanity_check((user.chan | pls.chan) & ~mns.chan,
147     user.global);
148     user.udef_chan = (user.udef_chan | pls.udef_chan) & ~mns.udef_chan;
149    
150     }
151     set_user_flagrec(u, &user, chan);
152     check_dcc_attrs(u, of);
153     if (chan)
154     check_dcc_chanattrs(u, chan, user.chan, ocf);
155     }
156     user.chan &= ~BOT_SHARE; /* actually not a user flag, hide it */
157     /* Build flag string */
158     build_flags(work, &user, NULL);
159     Tcl_AppendResult(irp, work, NULL);
160     return TCL_OK;
161     }
162    
163     static int tcl_botattr STDVAR
164     {
165     char *chan, *chg, work[100];
166     struct flag_record pls, mns, user;
167     struct userrec *u;
168    
169     BADARGS(2, 4, " bot-handle ?changes? ?channel?");
170    
171     u = get_user_by_handle(userlist, argv[1]);
172     if ((argv[1][0] == '*') || !u || !(u->flags & USER_BOT)) {
173     Tcl_AppendResult(irp, "*", NULL);
174     return TCL_OK;
175     }
176     if (argc == 4) {
177     user.match = FR_BOT | FR_CHAN;
178     chan = argv[3];
179     chg = argv[2];
180     } else if (argc == 3 && argv[2][0] && strchr(CHANMETA, argv[2][0]) != NULL) {
181     /* We need todo extra checking here to stop us mixing up +channel's
182     * with flags. <cybah>
183     */
184     if (!findchan_by_dname(argv[2]) && argv[2][0] != '+') {
185     /* Channel doesnt exist, and it cant possibly be flags as there
186     * is no + at the start of the string.
187     */
188     Tcl_AppendResult(irp, "no such channel", NULL);
189     return TCL_ERROR;
190     } else if (findchan_by_dname(argv[2])) {
191     /* Channel exists */
192     user.match = FR_BOT | FR_CHAN;
193     chan = argv[2];
194     chg = NULL;
195     } else {
196     /* 3rd possibility... channel doesnt exist, does start with a +.
197     * In this case we assume the string is flags.
198     */
199     user.match = FR_BOT;
200     chan = NULL;
201     chg = argv[2];
202     }
203     } else {
204     user.match = FR_BOT;
205     chan = NULL;
206     if (argc < 3)
207     chg = NULL;
208     else
209     chg = argv[2];
210     }
211     if (chan && !findchan_by_dname(chan)) {
212     Tcl_AppendResult(irp, "no such channel", NULL);
213     return TCL_ERROR;
214     }
215     /* Retrieve current flags */
216     get_user_flagrec(u, &user, chan);
217     /* Make changes */
218     if (chg) {
219     pls.match = user.match;
220     break_down_flags(chg, &pls, &mns);
221     /* No-one can change these flags on-the-fly */
222     if (chan) {
223     pls.chan &= BOT_SHARE;
224     mns.chan &= BOT_SHARE;
225     }
226     user.bot = sanity_check((user.bot | pls.bot) & ~mns.bot);
227     if (chan) {
228     user.chan = (user.chan | pls.chan) & ~mns.chan;
229     user.udef_chan = (user.udef_chan | pls.udef_chan) & ~mns.udef_chan;
230     }
231     set_user_flagrec(u, &user, chan);
232     }
233     /* Only user flags can be set per channel, not bot ones,
234     so BOT_SHARE is a hack to allow botattr |+s */
235     user.chan &= BOT_SHARE;
236     user.udef_chan = 0; /* User definable bot flags are global only,
237     anything here is a regular flag, so hide it. */
238     /* Build flag string */
239     build_flags(work, &user, NULL);
240     Tcl_AppendResult(irp, work, NULL);
241     return TCL_OK;
242     }
243    
244     static int tcl_matchattr STDVAR
245     {
246     struct userrec *u;
247     struct flag_record plus, minus, user;
248     int ok = 0, f;
249    
250     BADARGS(3, 4, " handle flags ?channel?");
251    
252     if ((u = get_user_by_handle(userlist, argv[1]))) {
253     user.match = FR_GLOBAL | (argc == 4 ? FR_CHAN : 0) | FR_BOT;
254     get_user_flagrec(u, &user, argv[3]);
255     plus.match = user.match;
256     break_down_flags(argv[2], &plus, &minus);
257     f = (minus.global || minus.udef_global || minus.chan || minus.udef_chan ||
258     minus.bot);
259     if (flagrec_eq(&plus, &user)) {
260     if (!f)
261     ok = 1;
262     else {
263     minus.match = plus.match ^ (FR_AND | FR_OR);
264     if (!flagrec_eq(&minus, &user))
265     ok = 1;
266     }
267     }
268     }
269     Tcl_AppendResult(irp, ok ? "1" : "0", NULL);
270     return TCL_OK;
271     }
272    
273     static int tcl_adduser STDVAR
274     {
275     unsigned char *p;
276    
277     BADARGS(2, 3, " handle ?hostmask?");
278    
279     if (strlen(argv[1]) > HANDLEN)
280     argv[1][HANDLEN] = 0;
281     for (p = (unsigned char *) argv[1]; *p; p++)
282     if (*p <= 32 || *p == '@')
283     *p = '?';
284    
285     if ((argv[1][0] == '*') || strchr(BADHANDCHARS, argv[1][0]) ||
286     get_user_by_handle(userlist, argv[1]))
287     Tcl_AppendResult(irp, "0", NULL);
288     else {
289     userlist = adduser(userlist, argv[1], argv[2], "-", default_flags);
290     Tcl_AppendResult(irp, "1", NULL);
291     }
292     return TCL_OK;
293     }
294    
295     static int tcl_addbot STDVAR
296     {
297     struct bot_addr *bi;
298     char *p, *q;
299    
300     BADARGS(3, 3, " handle address");
301    
302     if (strlen(argv[1]) > HANDLEN)
303     argv[1][HANDLEN] = 0;
304     for (p = argv[1]; *p; p++)
305     if ((unsigned char) *p <= 32 || *p == '@')
306     *p = '?';
307    
308     if ((argv[1][0] == '*') || strchr(BADHANDCHARS, argv[1][0]) ||
309     get_user_by_handle(userlist, argv[1]))
310     Tcl_AppendResult(irp, "0", NULL);
311     else {
312     userlist = adduser(userlist, argv[1], "none", "-", USER_BOT);
313     bi = user_malloc(sizeof(struct bot_addr));
314 pseudo 1.2 #ifdef IPV6
315     if ((q = strchr(argv[2], '/'))) {
316     if (!q[1]) {
317     *q = 0;
318     q = 0;
319     }
320     } else
321     #endif
322 simple 1.1 q = strchr(argv[2], ':');
323     if (!q) {
324     bi->address = user_malloc(strlen(argv[2]) + 1);
325     strcpy(bi->address, argv[2]);
326     bi->telnet_port = 3333;
327     bi->relay_port = 3333;
328     } else {
329     bi->address = user_malloc(q - argv[2] + 1);
330     strncpy(bi->address, argv[2], q - argv[2]);
331     bi->address[q - argv[2]] = 0;
332     p = q + 1;
333     bi->telnet_port = atoi(p);
334     q = strchr(p, '/');
335     if (!q)
336     bi->relay_port = bi->telnet_port;
337     else
338     bi->relay_port = atoi(q + 1);
339     }
340     set_user(&USERENTRY_BOTADDR, get_user_by_handle(userlist, argv[1]), bi);
341     Tcl_AppendResult(irp, "1", NULL);
342     }
343     return TCL_OK;
344     }
345    
346     static int tcl_deluser STDVAR
347     {
348     BADARGS(2, 2, " handle");
349    
350     Tcl_AppendResult(irp, (argv[1][0] == '*') ? "0" :
351     int_to_base10(deluser(argv[1])), NULL);
352     return TCL_OK;
353     }
354    
355     static int tcl_delhost STDVAR
356     {
357     BADARGS(3, 3, " handle hostmask");
358    
359     if ((!get_user_by_handle(userlist, argv[1])) || (argv[1][0] == '*')) {
360     Tcl_AppendResult(irp, "non-existent user", NULL);
361     return TCL_ERROR;
362     }
363     Tcl_AppendResult(irp, delhost_by_handle(argv[1], argv[2]) ? "1" : "0", NULL);
364     return TCL_OK;
365     }
366    
367     static int tcl_userlist STDVAR
368     {
369     struct userrec *u;
370     struct flag_record user, plus, minus;
371     int ok = 1, f = 0;
372    
373     BADARGS(1, 3, " ?flags ?channel??");
374    
375     if (argc == 3 && !findchan_by_dname(argv[2])) {
376     Tcl_AppendResult(irp, "Invalid channel: ", argv[2], NULL);
377     return TCL_ERROR;
378     }
379     if (argc >= 2) {
380     plus.match = FR_GLOBAL | FR_CHAN | FR_BOT;
381     break_down_flags(argv[1], &plus, &minus);
382     f = (minus.global ||minus.udef_global || minus.chan || minus.udef_chan ||
383     minus.bot);
384     }
385     minus.match = plus.match ^ (FR_AND | FR_OR);
386     for (u = userlist; u; u = u->next) {
387     if (argc >= 2) {
388     user.match = FR_GLOBAL | FR_CHAN | FR_BOT | (argc == 3 ? 0 : FR_ANYWH);
389     if (argc == 3)
390     get_user_flagrec(u, &user, argv[2]);
391     else
392     get_user_flagrec(u, &user, NULL);
393     if (flagrec_eq(&plus, &user) && !(f && flagrec_eq(&minus, &user)))
394     ok = 1;
395     else
396     ok = 0;
397     }
398     if (ok)
399     Tcl_AppendElement(interp, u->handle);
400     }
401     return TCL_OK;
402     }
403    
404     static int tcl_save STDVAR
405     {
406     write_userfile(-1);
407     return TCL_OK;
408     }
409    
410     static int tcl_reload STDVAR
411     {
412     reload();
413     return TCL_OK;
414     }
415    
416     static int tcl_chhandle STDVAR
417     {
418     struct userrec *u;
419     char newhand[HANDLEN + 1];
420     int x = 1, i;
421    
422     BADARGS(3, 3, " oldnick newnick");
423    
424     u = get_user_by_handle(userlist, argv[1]);
425     if (!u)
426     x = 0;
427     else {
428     strncpyz(newhand, argv[2], sizeof newhand);
429     for (i = 0; i < strlen(newhand); i++)
430     if (((unsigned char) newhand[i] <= 32) || (newhand[i] == '@'))
431     newhand[i] = '?';
432     if (strchr(BADHANDCHARS, newhand[0]) != NULL)
433     x = 0;
434     else if (strlen(newhand) < 1)
435     x = 0;
436     else if (get_user_by_handle(userlist, newhand))
437     x = 0;
438     else if (!egg_strcasecmp(botnetnick, newhand) && (!(u->flags & USER_BOT) ||
439     nextbot(argv[1]) != -1))
440     x = 0;
441     else if (newhand[0] == '*')
442     x = 0;
443     }
444     if (x)
445     x = change_handle(u, newhand);
446    
447     Tcl_AppendResult(irp, x ? "1" : "0", NULL);
448     return TCL_OK;
449     }
450    
451     static int tcl_getting_users STDVAR
452     {
453     int i;
454    
455     BADARGS(1, 1, "");
456    
457     for (i = 0; i < dcc_total; i++) {
458     if (dcc[i].type == &DCC_BOT && dcc[i].status & STAT_GETTING) {
459     Tcl_AppendResult(irp, "1", NULL);
460     return TCL_OK;
461     }
462     }
463     Tcl_AppendResult(irp, "0", NULL);
464     return TCL_OK;
465     }
466    
467     static int tcl_isignore STDVAR
468     {
469     BADARGS(2, 2, " nick!user@host");
470    
471     Tcl_AppendResult(irp, match_ignore(argv[1]) ? "1" : "0", NULL);
472     return TCL_OK;
473     }
474    
475     static int tcl_newignore STDVAR
476     {
477     time_t expire_time;
478     char ign[UHOSTLEN], cmt[66], from[HANDLEN + 1];
479    
480     BADARGS(4, 5, " hostmask creator comment ?lifetime?");
481    
482     strncpyz(ign, argv[1], sizeof ign);
483     strncpyz(from, argv[2], sizeof from);
484     strncpyz(cmt, argv[3], sizeof cmt);
485    
486     if (argc == 4)
487     expire_time = now + (60 * ignore_time);
488     else {
489     if (argc == 5 && atol(argv[4]) == 0)
490     expire_time = 0L;
491     else
492     expire_time = now + (60 * atol(argv[4])); /* This is a potential crash. FIXME -poptix */
493     }
494     addignore(ign, from, cmt, expire_time);
495     return TCL_OK;
496     }
497    
498     static int tcl_killignore STDVAR
499     {
500     BADARGS(2, 2, " hostmask");
501    
502     Tcl_AppendResult(irp, delignore(argv[1]) ? "1" : "0", NULL);
503     return TCL_OK;
504     }
505    
506     static int tcl_ignorelist STDVAR
507     {
508     char expire[11], added[11], *p;
509     long tv;
510     EGG_CONST char *list[5];
511     struct igrec *i;
512    
513     BADARGS(1, 1, "");
514    
515     for (i = global_ign; i; i = i->next) {
516     list[0] = i->igmask;
517     list[1] = i->msg;
518    
519     tv = i->expire;
520     egg_snprintf(expire, sizeof expire, "%lu", tv);
521     list[2] = expire;
522    
523     tv = i->added;
524     egg_snprintf(added, sizeof added, "%lu", tv);
525     list[3] = added;
526    
527     list[4] = i->user;
528     p = Tcl_Merge(5, list);
529     Tcl_AppendElement(irp, p);
530     Tcl_Free((char *) p);
531     }
532     return TCL_OK;
533     }
534    
535     static int tcl_getuser STDVAR
536     {
537     struct user_entry_type *et;
538     struct userrec *u;
539     struct user_entry *e;
540    
541     BADARGS(3, -1, " handle type");
542    
543     if (!(et = find_entry_type(argv[2])) && egg_strcasecmp(argv[2], "HANDLE")) {
544     Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
545     return TCL_ERROR;
546     }
547     if (!(u = get_user_by_handle(userlist, argv[1]))) {
548     if (argv[1][0] != '*') {
549     Tcl_AppendResult(irp, "No such user.", NULL);
550     return TCL_ERROR;
551     } else
552     return TCL_OK; /* silently ignore user */
553     }
554     if (!egg_strcasecmp(argv[2], "HANDLE"))
555     Tcl_AppendResult(irp, u->handle, NULL);
556     else {
557     e = find_user_entry(et, u);
558     if (e)
559     return et->tcl_get(irp, u, e, argc, argv);
560     }
561     return TCL_OK;
562     }
563    
564     static int tcl_setuser STDVAR
565     {
566     struct user_entry_type *et;
567     struct userrec *u;
568     struct user_entry *e;
569     int r;
570     module_entry *me;
571    
572     BADARGS(3, -1, " handle type ?setting....?");
573    
574     if (!(et = find_entry_type(argv[2]))) {
575     Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
576     return TCL_ERROR;
577     }
578     if (!(u = get_user_by_handle(userlist, argv[1]))) {
579     if (argv[1][0] != '*') {
580     Tcl_AppendResult(irp, "No such user.", NULL);
581     return TCL_ERROR;
582     } else
583     return TCL_OK; /* Silently ignore user * */
584     }
585     me = module_find("irc", 0, 0);
586     if (me && !strcmp(argv[2], "hosts") && argc == 3) {
587     Function *func = me->funcs;
588    
589     (func[IRC_CHECK_THIS_USER]) (argv[1], 1, NULL);
590     }
591     if (!(e = find_user_entry(et, u))) {
592     e = user_malloc(sizeof(struct user_entry));
593     e->type = et;
594     e->name = NULL;
595     e->u.list = NULL;
596     list_insert((&(u->entries)), e);
597     }
598     r = et->tcl_set(irp, u, e, argc, argv);
599     /* Yeah... e is freed, and we read it... (tcl: setuser hand HOSTS none) */
600     if ((!e->u.list) && (egg_list_delete((struct list_type **) &(u->entries),
601     (struct list_type *) e)))
602     nfree(e);
603     /* else maybe already freed... (entry_type==HOSTS) <drummer> */
604     if (me && !strcmp(argv[2], "hosts") && argc == 4) {
605     Function *func = me->funcs;
606    
607     (func[IRC_CHECK_THIS_USER]) (argv[1], 0, NULL);
608     }
609     return r;
610     }
611    
612     tcl_cmds tcluser_cmds[] = {
613     {"countusers", tcl_countusers},
614     {"validuser", tcl_validuser},
615     {"finduser", tcl_finduser},
616     {"passwdok", tcl_passwdOk},
617     {"chattr", tcl_chattr},
618     {"botattr", tcl_botattr},
619     {"matchattr", tcl_matchattr},
620     {"matchchanattr", tcl_matchattr},
621     {"adduser", tcl_adduser},
622     {"addbot", tcl_addbot},
623     {"deluser", tcl_deluser},
624     {"delhost", tcl_delhost},
625     {"userlist", tcl_userlist},
626     {"save", tcl_save},
627     {"reload", tcl_reload},
628     {"chhandle", tcl_chhandle},
629     {"chnick", tcl_chhandle},
630     {"getting-users", tcl_getting_users},
631     {"isignore", tcl_isignore},
632     {"newignore", tcl_newignore},
633     {"killignore", tcl_killignore},
634     {"ignorelist", tcl_ignorelist},
635     {"getuser", tcl_getuser},
636     {"setuser", tcl_setuser},
637     {NULL, NULL}
638     };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23