/[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.10 - (hide annotations) (download) (as text)
Wed Dec 15 02:32:58 1999 UTC (19 years, 8 months ago) by guppy
Branch: MAIN
Changes since 1.9: +21 -8 lines
File MIME type: text/x-chdr
id-header patch, finally, we have id tags for each file

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23