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

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

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


Revision 1.6 - (hide annotations) (download) (as text)
Thu Oct 21 20:04:00 1999 UTC (19 years, 10 months ago) by guppy
Branch: MAIN
Changes since 1.5: +3 -2 lines
File MIME type: text/x-chdr
more patches

1 segfault 1.1 /*
2     * tcluser.c -- handles:
3     * Tcl stubs for the user-record-oriented commands
4     *
5     * dprintf'ized, 1aug1996
6     */
7     /*
8     * This file is part of the eggdrop source code
9     * copyright (c) 1997 Robey Pointer
10     * and is distributed according to the GNU general public license.
11     * For full details, read the top of 'main.c' or the file called
12     * COPYING that was distributed with this code.
13     */
14    
15     #include "main.h"
16     #include "users.h"
17     #include "chan.h"
18     #include "tandem.h"
19    
20     /* eggdrop always uses the same interpreter */
21     extern Tcl_Interp *interp;
22     extern struct userrec *userlist;
23     extern int default_flags;
24     extern struct dcc_t *dcc;
25     extern int dcc_total;
26     extern char origbotname[];
27     extern char botnetnick[];
28     extern int ignore_time;
29     extern time_t now;
30    
31     /***********************************************************************/
32    
33     static int tcl_countusers STDVAR {
34     context;
35     BADARGS(1, 1, "");
36     Tcl_AppendResult(irp, int_to_base10(count_users(userlist)), NULL);
37     return TCL_OK;
38     }
39    
40     static int tcl_validuser STDVAR {
41     context;
42     BADARGS(2, 2, " handle");
43     Tcl_AppendResult(irp, get_user_by_handle(userlist, argv[1]) ? "1" : "0",
44     NULL);
45     return TCL_OK;
46     }
47     static int tcl_finduser STDVAR {
48     struct userrec *u;
49    
50     context;
51     BADARGS(2, 2, " nick!user@host");
52     u = get_user_by_host(argv[1]);
53     Tcl_AppendResult(irp, u ? u->handle : "*", NULL);
54     return TCL_OK;
55     }
56    
57     static int tcl_passwdOk STDVAR {
58     struct userrec *u;
59    
60     context;
61     BADARGS(3, 3, " handle passwd");
62     Tcl_AppendResult(irp, ((u = get_user_by_handle(userlist, argv[1])) &&
63     u_pass_match(u, argv[2])) ? "1" : "0", NULL);
64     return TCL_OK;
65     }
66    
67     static int tcl_chattr STDVAR {
68     char *chan, *chg, work[100];
69     struct flag_record pls, mns, user;
70     struct userrec *u;
71    
72     context;
73     BADARGS(2, 4, " handle ?changes? ?channel?");
74     if ((argv[1][0] == '*') || !(u = get_user_by_handle(userlist, argv[1]))) {
75     Tcl_AppendResult(irp, "*", NULL);
76     return TCL_OK;
77     }
78     if (argc == 4) {
79     user.match = FR_GLOBAL | FR_CHAN;
80     chan = argv[3];
81     chg = argv[2];
82 guppy 1.3 } else if ((argc == 3)
83     && (argv[2][0] && (strchr(CHANMETA, argv[2][0]) != NULL))) {
84 segfault 1.1 /* We need todo extra checking here to stop us mixing up +channel's
85     * with flags. <cybah> */
86     if (!findchan(argv[2]) && argv[2][0] != '+') {
87     /* Channel doesnt exist, and it cant possibly be flags as there
88     * is no + at the start of the string. */
89     Tcl_AppendResult(irp, "no such channel", NULL);
90     return TCL_ERROR;
91     } else if(findchan(argv[2])) {
92     /* Channel exists */
93     user.match = FR_GLOBAL | FR_CHAN;
94     chan = argv[2];
95     chg = NULL;
96     } else {
97     /* 3rd possibility... channel doesnt exist, does start with a +.
98     * In this case we assume the string is flags. */
99     user.match = FR_GLOBAL;
100     chan = NULL;
101     chg = argv[2];
102     }
103     } else {
104     user.match = FR_GLOBAL;
105     chan = NULL;
106     chg = argv[2];
107     }
108     if (chan && !findchan(chan)) {
109     Tcl_AppendResult(irp, "no such channel", NULL);
110     return TCL_ERROR;
111     }
112     get_user_flagrec(u, &user, chan);
113     /* make changes */
114     if (chg) {
115     pls.match = user.match;
116     break_down_flags(chg, &pls, &mns);
117     /* no-one can change these flags on-the-fly */
118     pls.global &=~(USER_BOT);
119     mns.global &=~(USER_BOT);
120     if (chan) {
121     pls.chan &= ~(BOT_SHARE);
122     mns.chan &= ~(BOT_SHARE);
123     }
124     user.global = sanity_check((user.global |pls.global) &~mns.global);
125     user.udef_global = (user.udef_global | pls.udef_global)
126     & ~mns.udef_global;
127     if (chan) {
128     user.chan = chan_sanity_check((user.chan | pls.chan) & ~mns.chan,
129     user.global);
130     user.udef_chan = (user.udef_chan | pls.udef_chan) & ~mns.udef_chan;
131     }
132     set_user_flagrec(u, &user, chan);
133     }
134     /* retrieve current flags and return them */
135     build_flags(work, &user, NULL);
136     Tcl_AppendResult(irp, work, NULL);
137     return TCL_OK;
138     }
139    
140     static int tcl_botattr STDVAR {
141     char *chan, *chg, work[100];
142     struct flag_record pls, mns, user;
143     struct userrec *u;
144    
145     context;
146     BADARGS(2, 4, " bot-handle ?changes? ?channel?");
147     u = get_user_by_handle(userlist, argv[1]);
148     if ((argv[1][0] == '*') || !u || !(u->flags & USER_BOT)) {
149     Tcl_AppendResult(irp, "*", NULL);
150     return TCL_OK;
151     }
152     if (argc == 4) {
153     user.match = FR_BOT | FR_CHAN;
154     chan = argv[3];
155     chg = argv[2];
156 guppy 1.3 } else if ((argc == 3)
157     && (argv[2][0] && (strchr(CHANMETA, argv[2][0]) != NULL))) {
158 segfault 1.1 /* We need todo extra checking here to stop us mixing up +channel's
159     * with flags. <cybah> */
160     if (!findchan(argv[2]) && argv[2][0] != '+') {
161     /* Channel doesnt exist, and it cant possibly be flags as there
162     * is no + at the start of the string. */
163     Tcl_AppendResult(irp, "no such channel", NULL);
164     return TCL_ERROR;
165     } else if(findchan(argv[2])) {
166     /* Channel exists */
167     user.match = FR_BOT | FR_CHAN;
168     chan = argv[2];
169     chg = NULL;
170     } else {
171     /* 3rd possibility... channel doesnt exist, does start with a +.
172     * In this case we assume the string is flags. */
173     user.match = FR_BOT;
174     chan = NULL;
175     chg = argv[2];
176     }
177     } else {
178     user.match = FR_BOT;
179     chan = NULL;
180     chg = argv[2];
181     }
182     if (chan && !findchan(chan)) {
183     Tcl_AppendResult(irp, "no such channel", NULL);
184     return TCL_ERROR;
185     }
186     get_user_flagrec(u, &user, chan);
187     /* make changes */
188     if (chg) {
189     pls.match = user.match;
190     break_down_flags(chg, &pls, &mns);
191     /* no-one can change these flags on-the-fly */
192     if (chan) {
193     pls.chan &= BOT_SHARE;
194     mns.chan &= BOT_SHARE;
195     }
196     user.bot = sanity_check((user.bot | pls.bot) & ~mns.bot);
197     if (chan) {
198     user.chan = chan_sanity_check((user.chan | pls.chan) & ~mns.chan,
199     user.global);
200     user.udef_chan = (user.udef_chan | pls.udef_chan) & ~mns.udef_chan;
201     }
202     set_user_flagrec(u, &user, chan);
203     }
204     /* retrieve current flags and return them */
205     build_flags(work, &user, NULL);
206     Tcl_AppendResult(irp, work, NULL);
207     return TCL_OK;
208     }
209    
210     static int tcl_matchattr STDVAR {
211     struct userrec *u;
212     struct flag_record plus, minus, user;
213     int ok = 0, f;
214    
215     context;
216     BADARGS(3, 4, " handle flags ?channel?");
217     context; /* a2 - Last context: tcluser.c/184 */
218     if ((u = get_user_by_handle(userlist, argv[1])) &&
219     ((argc == 3) || findchan(argv[3]))) {
220     context; /* a2 - Last context: tcluser.c/184 */
221     user.match = FR_GLOBAL | (argc == 4 ? FR_CHAN : 0) | FR_BOT;
222     get_user_flagrec(u, &user, argv[3]);
223     plus.match = user.match;
224     break_down_flags(argv[2], &plus, &minus);
225     f = (minus.global || minus.udef_global || minus.chan ||
226     minus.udef_chan || minus.bot);
227     if (flagrec_eq(&plus, &user)) {
228     context; /* a2 - Last context: tcluser.c/184 */
229     if (!f)
230     ok = 1;
231     else {
232     minus.match = plus.match ^ (FR_AND | FR_OR);
233     if (!flagrec_eq(&minus, &user))
234     ok = 1;
235     }
236     }
237     }
238     context; /* a2 - Last context: tcluser.c/184 */
239     Tcl_AppendResult(irp, ok ? "1" : "0", NULL);
240     return TCL_OK;
241     }
242    
243     static int tcl_adduser STDVAR {
244     context;
245     BADARGS(3, 3, " handle hostmask");
246     if (strlen(argv[1]) > HANDLEN)
247     argv[1][HANDLEN] = 0;
248     if ((argv[1][0] == '*') || get_user_by_handle(userlist, argv[1]))
249     Tcl_AppendResult(irp, "0", NULL);
250     else {
251     userlist = adduser(userlist, argv[1], argv[2], "-", default_flags);
252     Tcl_AppendResult(irp, "1", NULL);
253     }
254     return TCL_OK;
255     }
256    
257     static int tcl_addbot STDVAR {
258     struct bot_addr *bi;
259     char *p, *q;
260    
261     context;
262     BADARGS(3, 3, " handle address");
263     if (strlen(argv[1]) > HANDLEN)
264     argv[1][HANDLEN] = 0;
265     if (get_user_by_handle(userlist, argv[1]))
266     Tcl_AppendResult(irp, "0", NULL);
267     else if (argv[1][0] == '*')
268     Tcl_AppendResult(irp, "0", NULL);
269     else {
270     userlist = adduser(userlist, argv[1], "none", "-", USER_BOT);
271     bi = user_malloc(sizeof(struct bot_addr));
272     q = strchr(argv[2], ':');
273     if (!q) {
274     bi->address = user_malloc(strlen(argv[2]) + 1);
275     strcpy(bi->address, argv[2]);
276     bi->telnet_port = 3333;
277     bi->relay_port = 3333;
278     } else {
279     bi->address = user_malloc(q - argv[2] + 1);
280     strncpy(bi->address, argv[2], q - argv[2]);
281     bi->address[q - argv[2]] = 0;
282     p = q + 1;
283     bi->telnet_port = atoi(p);
284     q = strchr(p, '/');
285     if (!q)
286     bi->relay_port = bi->telnet_port;
287     else
288     bi->relay_port = atoi(q + 1);
289     }
290     set_user(&USERENTRY_BOTADDR, get_user_by_handle(userlist, argv[1]), bi);
291     Tcl_AppendResult(irp, "1", NULL);
292     }
293     return TCL_OK;
294     }
295    
296     static int tcl_deluser STDVAR {
297     context;
298     BADARGS(2, 2, " handle");
299     Tcl_AppendResult(irp, (argv[1][0] == '*') ? "0" :
300     int_to_base10(deluser(argv[1])), NULL);
301     return TCL_OK;
302     }
303    
304     static int tcl_delhost STDVAR {
305     context;
306     BADARGS(3, 3, " handle hostmask");
307     if ((!get_user_by_handle(userlist, argv[1])) || (argv[1][0] == '*')) {
308     Tcl_AppendResult(irp, "non-existent user", NULL);
309     return TCL_ERROR;
310     }
311     Tcl_AppendResult(irp, delhost_by_handle(argv[1], argv[2]) ? "1" : "0",
312     NULL);
313     return TCL_OK;
314     }
315    
316     static int tcl_userlist STDVAR {
317     struct userrec *u = userlist;
318     struct flag_record user, plus, minus;
319     int ok = 1, f = 0;
320    
321     context;
322     BADARGS(1, 3, " ?flags ?channel??");
323     if ((argc == 3) && !findchan(argv[2])) {
324     Tcl_AppendResult(irp, "Invalid channel: ", argv[2], NULL);
325     return TCL_ERROR;
326     }
327     if (argc >= 2) {
328     plus.match = FR_GLOBAL | FR_CHAN | FR_BOT;
329     break_down_flags(argv[1], &plus, &minus);
330     f = (minus.global || minus.udef_global || minus.chan ||
331     minus.udef_chan || minus.bot);
332     }
333     minus.match = plus.match ^ (FR_AND | FR_OR);
334     while (u) {
335     if (argc >= 2) {
336     user.match = FR_GLOBAL | FR_CHAN | FR_BOT | (argc == 3 ? 0 : FR_ANYWH);
337     get_user_flagrec(u, &user, argv[2]); /* argv[2] == NULL for argc = 2 ;) */
338     if (flagrec_eq(&plus, &user) && !(f && flagrec_eq(&minus, &user)))
339     ok = 1;
340     else
341     ok = 0;
342     }
343     if (ok)
344     Tcl_AppendElement(interp, u->handle);
345     u = u->next;
346     }
347     return TCL_OK;
348     }
349    
350     static int tcl_save STDVAR {
351     context;
352     write_userfile(-1);
353     return TCL_OK;
354     }
355    
356     static int tcl_reload STDVAR {
357     context;
358     reload();
359     return TCL_OK;
360     }
361    
362     static int tcl_chnick STDVAR {
363     struct userrec *u;
364 guppy 1.5 char newhand[HANDLEN + 1];
365 segfault 1.1 int x = 1, i;
366    
367     context;
368     BADARGS(3, 3, " oldnick newnick");
369     u = get_user_by_handle(userlist, argv[1]);
370     if (!u)
371     x = 0;
372     else {
373 guppy 1.5 strncpy(newhand, argv[2], HANDLEN);
374     newhand[HANDLEN] = 0;
375     for (i = 0; i < strlen(newhand); i++)
376     if ((newhand[i] <= 32) || (newhand[i] >= 127) || (newhand[i] == '@'))
377     newhand[i] = '?';
378     if (strchr(BADHANDCHARS, newhand[0]) != NULL)
379 segfault 1.1 x = 0;
380 guppy 1.5 else if (strlen(newhand) < 1)
381 segfault 1.1 x = 0;
382 guppy 1.5 else if (get_user_by_handle(userlist, newhand))
383 segfault 1.1 x = 0;
384 guppy 1.6 else if (!strcasecmp(botnetnick, newhand) &&
385     (!(u->flags & USER_BOT) || nextbot (argv [1]) != -1))
386     x = 0;
387 guppy 1.5 else if (newhand[0] == '*')
388 segfault 1.1 x = 0;
389     }
390     if (x)
391 guppy 1.5 x = change_handle(u, newhand);
392 segfault 1.1
393     Tcl_AppendResult(irp, x ? "1" : "0", NULL);
394     return TCL_OK;
395     }
396    
397     static int tcl_getting_users STDVAR {
398     int i;
399    
400     context;
401     BADARGS(1, 1, "");
402     for (i = 0; i < dcc_total; i++) {
403     if ((dcc[i].type == &DCC_BOT) &&
404     (dcc[i].status & STAT_GETTING)) {
405     Tcl_AppendResult(irp, "1", NULL);
406     return TCL_OK;
407     }
408     }
409     Tcl_AppendResult(irp, "0", NULL);
410     return TCL_OK;
411     }
412    
413     static int tcl_isignore STDVAR {
414     context;
415     BADARGS(2, 2, " nick!user@host");
416     Tcl_AppendResult(irp, match_ignore(argv[1]) ? "1" : "0", NULL);
417     return TCL_OK;
418     }
419    
420     static int tcl_newignore STDVAR {
421     time_t expire_time;
422     char ign[UHOSTLEN], cmt[66], from[HANDLEN + 1];
423    
424     context;
425     BADARGS(4, 5, " hostmask creator comment ?lifetime?");
426 guppy 1.5 strncpy(ign, argv[1], UHOSTMAX);
427     ign[UHOSTMAX] = 0;
428 segfault 1.1 strncpy(from, argv[2], HANDLEN);
429     from[HANDLEN] = 0;
430     strncpy(cmt, argv[3], 65);
431     cmt[65] = 0;
432     if (argc == 4)
433     expire_time = now + (60 * ignore_time);
434     else {
435     if (atol(argv[4]) == 0)
436     expire_time = 0L;
437     else
438     expire_time = now + (60 * atol(argv[4]));
439     }
440     addignore(ign, from, cmt, expire_time);
441    
442     return TCL_OK;
443     }
444    
445     static int tcl_killignore STDVAR {
446     context;
447     BADARGS(2, 2, " hostmask");
448     Tcl_AppendResult(irp, delignore(argv[1]) ? "1" : "0", NULL);
449     return TCL_OK;
450     }
451    
452     /* { hostmask note expire-time create-time creator } */
453     static int tcl_ignorelist STDVAR {
454     struct igrec *i;
455     char ts[21], ts1[21], *list[5], *p;
456    
457     context;
458     BADARGS(1, 1, "");
459     for (i = global_ign; i; i = i->next) {
460     list[0] = i->igmask;
461     list[1] = i->msg;
462     sprintf(ts, "%lu", i->expire);
463     list[2] = ts;
464     sprintf(ts1, "%lu", i->added);
465     list[3] = ts1;
466     list[4] = i->user;
467     p = Tcl_Merge(5, list);
468     Tcl_AppendElement(irp, p);
469     n_free(p, "", 0);
470     }
471     return TCL_OK;
472     }
473    
474     static int tcl_getuser STDVAR {
475     struct user_entry_type *et;
476     struct userrec *u;
477     struct user_entry *e;
478    
479     context;
480     BADARGS(3, 999, " handle type");
481     if (!(et = find_entry_type(argv[2]))) {
482     Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
483     return TCL_ERROR;
484     }
485     if (!(u = get_user_by_handle(userlist, argv[1]))) {
486     if (argv[1][0] != '*') {
487     Tcl_AppendResult(irp, "No such user.", NULL);
488     return TCL_ERROR;
489     } else
490     return TCL_OK; /* silently ignore user * */
491     }
492     e = find_user_entry(et, u);
493    
494     if (e)
495     return et->tcl_get(irp, u, e, argc, argv);
496     return TCL_OK;
497     }
498    
499     static int tcl_setuser STDVAR {
500     struct user_entry_type *et;
501     struct userrec *u;
502     struct user_entry *e;
503     int r;
504    
505     context;
506     BADARGS(3, 999, " handle type ?setting....?");
507     if (!(et = find_entry_type(argv[2]))) {
508     Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
509     return TCL_ERROR;
510     }
511     if (!(u = get_user_by_handle(userlist, argv[1]))) {
512     if (argv[1][0] != '*') {
513     Tcl_AppendResult(irp, "No such user.", NULL);
514     return TCL_ERROR;
515     } else
516     return TCL_OK; /* silently ignore user * */
517     }
518     if (!(e = find_user_entry(et, u))) {
519     e = user_malloc(sizeof(struct user_entry));
520    
521     e->type = et;
522     e->name = NULL;
523     e->u.list = NULL;
524     list_insert((&(u->entries)), e);
525     }
526     r = et->tcl_set(irp, u, e, argc, argv);
527 guppy 1.2 /* yeah... e is freed, and we read it... (tcl: setuser hand HOSTS none) */
528 segfault 1.1 if (!e->u.list) {
529 arthur2 1.4 if (list_delete((struct list_type **) &(u->entries),
530     (struct list_type *) e))
531     nfree(e);
532 guppy 1.2 /* else maybe already freed... (entry_type==HOSTS) <drummer> */
533 segfault 1.1 }
534     return r;
535     }
536    
537     tcl_cmds tcluser_cmds[] =
538     {
539     {"countusers", tcl_countusers},
540     {"validuser", tcl_validuser},
541     {"finduser", tcl_finduser},
542     {"passwdok", tcl_passwdOk},
543     {"chattr", tcl_chattr},
544     {"botattr", tcl_botattr},
545     {"matchattr", tcl_matchattr},
546     {"matchchanattr", tcl_matchattr},
547     {"adduser", tcl_adduser},
548     {"addbot", tcl_addbot},
549     {"deluser", tcl_deluser},
550     {"delhost", tcl_delhost},
551     {"userlist", tcl_userlist},
552     {"save", tcl_save},
553     {"reload", tcl_reload},
554     {"chnick", tcl_chnick},
555     {"getting-users", tcl_getting_users},
556     {"isignore", tcl_isignore},
557     {"newignore", tcl_newignore},
558     {"killignore", tcl_killignore},
559     {"ignorelist", tcl_ignorelist},
560     {"getuser", tcl_getuser},
561     {"setuser", tcl_setuser},
562     {0, 0}
563     };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23