/[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.12 - (hide annotations) (download) (as text)
Mon Jan 17 16:14:45 2000 UTC (19 years, 7 months ago) by per
Branch: MAIN
CVS Tags: eggdrop10402RC1, eggdrop10402
Changes since 1.11: +3 -6 lines
File MIME type: text/x-chdr
relayfix, extern_cleanup

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23