/[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.1.1.1 - (hide annotations) (download) (as text) (vendor branch)
Mon Jul 26 21:11:06 2010 UTC (9 years, 2 months ago) by simple
Branch: eggheads
CVS Tags: v1
Changes since 1.1: +0 -0 lines
File MIME type: text/x-chdr
Imported Eggdrop 1.6.20

1 simple 1.1 /*
2     * tcluser.c -- handles:
3     * Tcl stubs for the user-record-oriented commands
4     *
5     * $Id: tcluser.c,v 1.51 2010/07/01 16:10:49 thommey Exp $
6     */
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     q = strchr(argv[2], ':');
315     if (!q) {
316     bi->address = user_malloc(strlen(argv[2]) + 1);
317     strcpy(bi->address, argv[2]);
318     bi->telnet_port = 3333;
319     bi->relay_port = 3333;
320     } else {
321     bi->address = user_malloc(q - argv[2] + 1);
322     strncpy(bi->address, argv[2], q - argv[2]);
323     bi->address[q - argv[2]] = 0;
324     p = q + 1;
325     bi->telnet_port = atoi(p);
326     q = strchr(p, '/');
327     if (!q)
328     bi->relay_port = bi->telnet_port;
329     else
330     bi->relay_port = atoi(q + 1);
331     }
332     set_user(&USERENTRY_BOTADDR, get_user_by_handle(userlist, argv[1]), bi);
333     Tcl_AppendResult(irp, "1", NULL);
334     }
335     return TCL_OK;
336     }
337    
338     static int tcl_deluser STDVAR
339     {
340     BADARGS(2, 2, " handle");
341    
342     Tcl_AppendResult(irp, (argv[1][0] == '*') ? "0" :
343     int_to_base10(deluser(argv[1])), NULL);
344     return TCL_OK;
345     }
346    
347     static int tcl_delhost STDVAR
348     {
349     BADARGS(3, 3, " handle hostmask");
350    
351     if ((!get_user_by_handle(userlist, argv[1])) || (argv[1][0] == '*')) {
352     Tcl_AppendResult(irp, "non-existent user", NULL);
353     return TCL_ERROR;
354     }
355     Tcl_AppendResult(irp, delhost_by_handle(argv[1], argv[2]) ? "1" : "0", NULL);
356     return TCL_OK;
357     }
358    
359     static int tcl_userlist STDVAR
360     {
361     struct userrec *u;
362     struct flag_record user, plus, minus;
363     int ok = 1, f = 0;
364    
365     BADARGS(1, 3, " ?flags ?channel??");
366    
367     if (argc == 3 && !findchan_by_dname(argv[2])) {
368     Tcl_AppendResult(irp, "Invalid channel: ", argv[2], NULL);
369     return TCL_ERROR;
370     }
371     if (argc >= 2) {
372     plus.match = FR_GLOBAL | FR_CHAN | FR_BOT;
373     break_down_flags(argv[1], &plus, &minus);
374     f = (minus.global ||minus.udef_global || minus.chan || minus.udef_chan ||
375     minus.bot);
376     }
377     minus.match = plus.match ^ (FR_AND | FR_OR);
378     for (u = userlist; u; u = u->next) {
379     if (argc >= 2) {
380     user.match = FR_GLOBAL | FR_CHAN | FR_BOT | (argc == 3 ? 0 : FR_ANYWH);
381     if (argc == 3)
382     get_user_flagrec(u, &user, argv[2]);
383     else
384     get_user_flagrec(u, &user, NULL);
385     if (flagrec_eq(&plus, &user) && !(f && flagrec_eq(&minus, &user)))
386     ok = 1;
387     else
388     ok = 0;
389     }
390     if (ok)
391     Tcl_AppendElement(interp, u->handle);
392     }
393     return TCL_OK;
394     }
395    
396     static int tcl_save STDVAR
397     {
398     write_userfile(-1);
399     return TCL_OK;
400     }
401    
402     static int tcl_reload STDVAR
403     {
404     reload();
405     return TCL_OK;
406     }
407    
408     static int tcl_chhandle STDVAR
409     {
410     struct userrec *u;
411     char newhand[HANDLEN + 1];
412     int x = 1, i;
413    
414     BADARGS(3, 3, " oldnick newnick");
415    
416     u = get_user_by_handle(userlist, argv[1]);
417     if (!u)
418     x = 0;
419     else {
420     strncpyz(newhand, argv[2], sizeof newhand);
421     for (i = 0; i < strlen(newhand); i++)
422     if (((unsigned char) newhand[i] <= 32) || (newhand[i] == '@'))
423     newhand[i] = '?';
424     if (strchr(BADHANDCHARS, newhand[0]) != NULL)
425     x = 0;
426     else if (strlen(newhand) < 1)
427     x = 0;
428     else if (get_user_by_handle(userlist, newhand))
429     x = 0;
430     else if (!egg_strcasecmp(botnetnick, newhand) && (!(u->flags & USER_BOT) ||
431     nextbot(argv[1]) != -1))
432     x = 0;
433     else if (newhand[0] == '*')
434     x = 0;
435     }
436     if (x)
437     x = change_handle(u, newhand);
438    
439     Tcl_AppendResult(irp, x ? "1" : "0", NULL);
440     return TCL_OK;
441     }
442    
443     static int tcl_getting_users STDVAR
444     {
445     int i;
446    
447     BADARGS(1, 1, "");
448    
449     for (i = 0; i < dcc_total; i++) {
450     if (dcc[i].type == &DCC_BOT && dcc[i].status & STAT_GETTING) {
451     Tcl_AppendResult(irp, "1", NULL);
452     return TCL_OK;
453     }
454     }
455     Tcl_AppendResult(irp, "0", NULL);
456     return TCL_OK;
457     }
458    
459     static int tcl_isignore STDVAR
460     {
461     BADARGS(2, 2, " nick!user@host");
462    
463     Tcl_AppendResult(irp, match_ignore(argv[1]) ? "1" : "0", NULL);
464     return TCL_OK;
465     }
466    
467     static int tcl_newignore STDVAR
468     {
469     time_t expire_time;
470     char ign[UHOSTLEN], cmt[66], from[HANDLEN + 1];
471    
472     BADARGS(4, 5, " hostmask creator comment ?lifetime?");
473    
474     strncpyz(ign, argv[1], sizeof ign);
475     strncpyz(from, argv[2], sizeof from);
476     strncpyz(cmt, argv[3], sizeof cmt);
477    
478     if (argc == 4)
479     expire_time = now + (60 * ignore_time);
480     else {
481     if (argc == 5 && atol(argv[4]) == 0)
482     expire_time = 0L;
483     else
484     expire_time = now + (60 * atol(argv[4])); /* This is a potential crash. FIXME -poptix */
485     }
486     addignore(ign, from, cmt, expire_time);
487     return TCL_OK;
488     }
489    
490     static int tcl_killignore STDVAR
491     {
492     BADARGS(2, 2, " hostmask");
493    
494     Tcl_AppendResult(irp, delignore(argv[1]) ? "1" : "0", NULL);
495     return TCL_OK;
496     }
497    
498     static int tcl_ignorelist STDVAR
499     {
500     char expire[11], added[11], *p;
501     long tv;
502     EGG_CONST char *list[5];
503     struct igrec *i;
504    
505     BADARGS(1, 1, "");
506    
507     for (i = global_ign; i; i = i->next) {
508     list[0] = i->igmask;
509     list[1] = i->msg;
510    
511     tv = i->expire;
512     egg_snprintf(expire, sizeof expire, "%lu", tv);
513     list[2] = expire;
514    
515     tv = i->added;
516     egg_snprintf(added, sizeof added, "%lu", tv);
517     list[3] = added;
518    
519     list[4] = i->user;
520     p = Tcl_Merge(5, list);
521     Tcl_AppendElement(irp, p);
522     Tcl_Free((char *) p);
523     }
524     return TCL_OK;
525     }
526    
527     static int tcl_getuser STDVAR
528     {
529     struct user_entry_type *et;
530     struct userrec *u;
531     struct user_entry *e;
532    
533     BADARGS(3, -1, " handle type");
534    
535     if (!(et = find_entry_type(argv[2])) && egg_strcasecmp(argv[2], "HANDLE")) {
536     Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
537     return TCL_ERROR;
538     }
539     if (!(u = get_user_by_handle(userlist, argv[1]))) {
540     if (argv[1][0] != '*') {
541     Tcl_AppendResult(irp, "No such user.", NULL);
542     return TCL_ERROR;
543     } else
544     return TCL_OK; /* silently ignore user */
545     }
546     if (!egg_strcasecmp(argv[2], "HANDLE"))
547     Tcl_AppendResult(irp, u->handle, NULL);
548     else {
549     e = find_user_entry(et, u);
550     if (e)
551     return et->tcl_get(irp, u, e, argc, argv);
552     }
553     return TCL_OK;
554     }
555    
556     static int tcl_setuser STDVAR
557     {
558     struct user_entry_type *et;
559     struct userrec *u;
560     struct user_entry *e;
561     int r;
562     module_entry *me;
563    
564     BADARGS(3, -1, " handle type ?setting....?");
565    
566     if (!(et = find_entry_type(argv[2]))) {
567     Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
568     return TCL_ERROR;
569     }
570     if (!(u = get_user_by_handle(userlist, argv[1]))) {
571     if (argv[1][0] != '*') {
572     Tcl_AppendResult(irp, "No such user.", NULL);
573     return TCL_ERROR;
574     } else
575     return TCL_OK; /* Silently ignore user * */
576     }
577     me = module_find("irc", 0, 0);
578     if (me && !strcmp(argv[2], "hosts") && argc == 3) {
579     Function *func = me->funcs;
580    
581     (func[IRC_CHECK_THIS_USER]) (argv[1], 1, NULL);
582     }
583     if (!(e = find_user_entry(et, u))) {
584     e = user_malloc(sizeof(struct user_entry));
585     e->type = et;
586     e->name = NULL;
587     e->u.list = NULL;
588     list_insert((&(u->entries)), e);
589     }
590     r = et->tcl_set(irp, u, e, argc, argv);
591     /* Yeah... e is freed, and we read it... (tcl: setuser hand HOSTS none) */
592     if ((!e->u.list) && (egg_list_delete((struct list_type **) &(u->entries),
593     (struct list_type *) e)))
594     nfree(e);
595     /* else maybe already freed... (entry_type==HOSTS) <drummer> */
596     if (me && !strcmp(argv[2], "hosts") && argc == 4) {
597     Function *func = me->funcs;
598    
599     (func[IRC_CHECK_THIS_USER]) (argv[1], 0, NULL);
600     }
601     return r;
602     }
603    
604     tcl_cmds tcluser_cmds[] = {
605     {"countusers", tcl_countusers},
606     {"validuser", tcl_validuser},
607     {"finduser", tcl_finduser},
608     {"passwdok", tcl_passwdOk},
609     {"chattr", tcl_chattr},
610     {"botattr", tcl_botattr},
611     {"matchattr", tcl_matchattr},
612     {"matchchanattr", tcl_matchattr},
613     {"adduser", tcl_adduser},
614     {"addbot", tcl_addbot},
615     {"deluser", tcl_deluser},
616     {"delhost", tcl_delhost},
617     {"userlist", tcl_userlist},
618     {"save", tcl_save},
619     {"reload", tcl_reload},
620     {"chhandle", tcl_chhandle},
621     {"chnick", tcl_chhandle},
622     {"getting-users", tcl_getting_users},
623     {"isignore", tcl_isignore},
624     {"newignore", tcl_newignore},
625     {"killignore", tcl_killignore},
626     {"ignorelist", tcl_ignorelist},
627     {"getuser", tcl_getuser},
628     {"setuser", tcl_setuser},
629     {NULL, NULL}
630     };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23