/[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.5 - (hide annotations) (download) (as text)
Sun Oct 17 20:27:29 1999 UTC (19 years, 10 months ago) by guppy
Branch: MAIN
Changes since 1.4: +15 -15 lines
File MIME type: text/x-chdr
lots of 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.5 else if ((!strcasecmp(origbotname, newhand) || !rfc_casecmp(botnetnick, newhand)) &&
385     (!(u->flags & USER_BOT) || nextbot (argv [1]) != -1)) x = 0;
386     else if (newhand[0] == '*')
387 segfault 1.1 x = 0;
388     }
389     if (x)
390 guppy 1.5 x = change_handle(u, newhand);
391 segfault 1.1
392     Tcl_AppendResult(irp, x ? "1" : "0", NULL);
393     return TCL_OK;
394     }
395    
396     static int tcl_getting_users STDVAR {
397     int i;
398    
399     context;
400     BADARGS(1, 1, "");
401     for (i = 0; i < dcc_total; i++) {
402     if ((dcc[i].type == &DCC_BOT) &&
403     (dcc[i].status & STAT_GETTING)) {
404     Tcl_AppendResult(irp, "1", NULL);
405     return TCL_OK;
406     }
407     }
408     Tcl_AppendResult(irp, "0", NULL);
409     return TCL_OK;
410     }
411    
412     static int tcl_isignore STDVAR {
413     context;
414     BADARGS(2, 2, " nick!user@host");
415     Tcl_AppendResult(irp, match_ignore(argv[1]) ? "1" : "0", NULL);
416     return TCL_OK;
417     }
418    
419     static int tcl_newignore STDVAR {
420     time_t expire_time;
421     char ign[UHOSTLEN], cmt[66], from[HANDLEN + 1];
422    
423     context;
424     BADARGS(4, 5, " hostmask creator comment ?lifetime?");
425 guppy 1.5 strncpy(ign, argv[1], UHOSTMAX);
426     ign[UHOSTMAX] = 0;
427 segfault 1.1 strncpy(from, argv[2], HANDLEN);
428     from[HANDLEN] = 0;
429     strncpy(cmt, argv[3], 65);
430     cmt[65] = 0;
431     if (argc == 4)
432     expire_time = now + (60 * ignore_time);
433     else {
434     if (atol(argv[4]) == 0)
435     expire_time = 0L;
436     else
437     expire_time = now + (60 * atol(argv[4]));
438     }
439     addignore(ign, from, cmt, expire_time);
440    
441     return TCL_OK;
442     }
443    
444     static int tcl_killignore STDVAR {
445     context;
446     BADARGS(2, 2, " hostmask");
447     Tcl_AppendResult(irp, delignore(argv[1]) ? "1" : "0", NULL);
448     return TCL_OK;
449     }
450    
451     /* { hostmask note expire-time create-time creator } */
452     static int tcl_ignorelist STDVAR {
453     struct igrec *i;
454     char ts[21], ts1[21], *list[5], *p;
455    
456     context;
457     BADARGS(1, 1, "");
458     for (i = global_ign; i; i = i->next) {
459     list[0] = i->igmask;
460     list[1] = i->msg;
461     sprintf(ts, "%lu", i->expire);
462     list[2] = ts;
463     sprintf(ts1, "%lu", i->added);
464     list[3] = ts1;
465     list[4] = i->user;
466     p = Tcl_Merge(5, list);
467     Tcl_AppendElement(irp, p);
468     n_free(p, "", 0);
469     }
470     return TCL_OK;
471     }
472    
473     static int tcl_getuser STDVAR {
474     struct user_entry_type *et;
475     struct userrec *u;
476     struct user_entry *e;
477    
478     context;
479     BADARGS(3, 999, " handle type");
480     if (!(et = find_entry_type(argv[2]))) {
481     Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
482     return TCL_ERROR;
483     }
484     if (!(u = get_user_by_handle(userlist, argv[1]))) {
485     if (argv[1][0] != '*') {
486     Tcl_AppendResult(irp, "No such user.", NULL);
487     return TCL_ERROR;
488     } else
489     return TCL_OK; /* silently ignore user * */
490     }
491     e = find_user_entry(et, u);
492    
493     if (e)
494     return et->tcl_get(irp, u, e, argc, argv);
495     return TCL_OK;
496     }
497    
498     static int tcl_setuser STDVAR {
499     struct user_entry_type *et;
500     struct userrec *u;
501     struct user_entry *e;
502     int r;
503    
504     context;
505     BADARGS(3, 999, " handle type ?setting....?");
506     if (!(et = find_entry_type(argv[2]))) {
507     Tcl_AppendResult(irp, "No such info type: ", argv[2], NULL);
508     return TCL_ERROR;
509     }
510     if (!(u = get_user_by_handle(userlist, argv[1]))) {
511     if (argv[1][0] != '*') {
512     Tcl_AppendResult(irp, "No such user.", NULL);
513     return TCL_ERROR;
514     } else
515     return TCL_OK; /* silently ignore user * */
516     }
517     if (!(e = find_user_entry(et, u))) {
518     e = user_malloc(sizeof(struct user_entry));
519    
520     e->type = et;
521     e->name = NULL;
522     e->u.list = NULL;
523     list_insert((&(u->entries)), e);
524     }
525     r = et->tcl_set(irp, u, e, argc, argv);
526 guppy 1.2 /* yeah... e is freed, and we read it... (tcl: setuser hand HOSTS none) */
527 segfault 1.1 if (!e->u.list) {
528 arthur2 1.4 if (list_delete((struct list_type **) &(u->entries),
529     (struct list_type *) e))
530     nfree(e);
531 guppy 1.2 /* else maybe already freed... (entry_type==HOSTS) <drummer> */
532 segfault 1.1 }
533     return r;
534     }
535    
536     tcl_cmds tcluser_cmds[] =
537     {
538     {"countusers", tcl_countusers},
539     {"validuser", tcl_validuser},
540     {"finduser", tcl_finduser},
541     {"passwdok", tcl_passwdOk},
542     {"chattr", tcl_chattr},
543     {"botattr", tcl_botattr},
544     {"matchattr", tcl_matchattr},
545     {"matchchanattr", tcl_matchattr},
546     {"adduser", tcl_adduser},
547     {"addbot", tcl_addbot},
548     {"deluser", tcl_deluser},
549     {"delhost", tcl_delhost},
550     {"userlist", tcl_userlist},
551     {"save", tcl_save},
552     {"reload", tcl_reload},
553     {"chnick", tcl_chnick},
554     {"getting-users", tcl_getting_users},
555     {"isignore", tcl_isignore},
556     {"newignore", tcl_newignore},
557     {"killignore", tcl_killignore},
558     {"ignorelist", tcl_ignorelist},
559     {"getuser", tcl_getuser},
560     {"setuser", tcl_setuser},
561     {0, 0}
562     };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23