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

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

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


Revision 1.31 - (hide annotations) (download) (as text)
Sat Dec 1 16:33:38 2001 UTC (17 years, 11 months ago) by ite
Branch: MAIN
Changes since 1.30: +5 -2 lines
File MIME type: text/x-chdr
Fixed more potential crashes in botattr command. Patch by TaKeDa <takeda@eggheads.w.pl>

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23