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

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

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


Revision 1.19 - (hide annotations) (download) (as text)
Mon Feb 26 03:56:18 2001 UTC (18 years, 5 months ago) by guppy
Branch: MAIN
Changes since 1.18: +5 -5 lines
File MIME type: text/x-chdr
this memory leak has existed for a long time, pre 1.6 :P~

1 fabian 1.10 /*
2 segfault 1.1 * userent.c -- handles:
3 fabian 1.10 * user-entry handling, new stylem more versatile.
4     *
5 guppy 1.19 * $Id: userent.c,v 1.18 2000/12/19 21:56:40 guppy Exp $
6 segfault 1.1 */
7 fabian 1.10 /*
8     * Copyright (C) 1997 Robey Pointer
9 fabian 1.11 * Copyright (C) 1999, 2000 Eggheads
10 fabian 1.10 *
11     * 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     *
16     * 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     *
21     * 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 fabian 1.10
26 segfault 1.1 #include "main.h"
27     #include "users.h"
28    
29 fabian 1.12 extern int noshare;
30     extern struct userrec *userlist;
31     extern struct dcc_t *dcc;
32     extern Tcl_Interp *interp;
33     extern char whois_fields[];
34 segfault 1.1
35    
36 fabian 1.12 int share_greet = 0; /* Share greeting info */
37 segfault 1.1 static struct user_entry_type *entry_type_list;
38    
39 fabian 1.12
40 segfault 1.1 void init_userent()
41     {
42     entry_type_list = 0;
43     add_entry_type(&USERENTRY_COMMENT);
44     add_entry_type(&USERENTRY_XTRA);
45     add_entry_type(&USERENTRY_INFO);
46     add_entry_type(&USERENTRY_LASTON);
47     add_entry_type(&USERENTRY_BOTADDR);
48     add_entry_type(&USERENTRY_PASS);
49     add_entry_type(&USERENTRY_HOSTS);
50     add_entry_type(&USERENTRY_BOTFL);
51     }
52    
53     void list_type_kill(struct list_type *t)
54     {
55     struct list_type *u;
56    
57     while (t) {
58     u = t->next;
59     if (t->extra)
60     nfree(t->extra);
61     nfree(t);
62     t = u;
63     }
64     }
65    
66     int list_type_expmem(struct list_type *t)
67     {
68     int tot = 0;
69    
70     for (; t; t = t->next)
71     tot += sizeof(struct list_type) + strlen(t->extra) + 1;
72    
73     return tot;
74     }
75    
76     int def_unpack(struct userrec *u, struct user_entry *e)
77     {
78 fabian 1.3 char *tmp;
79    
80     tmp = e->u.list->extra;
81     e->u.list->extra = NULL;
82     list_type_kill(e->u.list);
83     e->u.string = tmp;
84 segfault 1.1 return 1;
85     }
86    
87     int def_pack(struct userrec *u, struct user_entry *e)
88     {
89 fabian 1.3 char *tmp;
90 segfault 1.1
91 fabian 1.3 tmp = e->u.string;
92     e->u.list = user_malloc(sizeof(struct list_type));
93     e->u.list->next = NULL;
94     e->u.list->extra = tmp;
95 segfault 1.1 return 1;
96     }
97    
98     int def_kill(struct user_entry *e)
99     {
100     nfree(e->u.string);
101     nfree(e);
102     return 1;
103     }
104    
105     int def_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
106     {
107     if (fprintf(f, "--%s %s\n", e->type->name, e->u.string) == EOF)
108     return 0;
109     return 1;
110     }
111    
112     void *def_get(struct userrec *u, struct user_entry *e)
113     {
114     return e->u.string;
115     }
116    
117     int def_set(struct userrec *u, struct user_entry *e, void *buf)
118     {
119 fabian 1.4 char *string = (char *) buf;
120 fabian 1.16
121 fabian 1.4 if (string && !string[0])
122     string = NULL;
123     if (!string && !e->u.string)
124     return 1;
125     if (string) {
126     int l = strlen (string);
127     char *i;
128    
129     if (l > 160)
130     l = 160;
131    
132    
133     e->u.string = user_realloc (e->u.string, l + 1);
134    
135 guppy 1.18 strncpyz (e->u.string, string, l + 1);
136 fabian 1.4
137     for (i = e->u.string; *i; i++)
138     /* Allow bold, inverse, underline, color text here...
139 fabian 1.12 * But never add cr or lf!! --rtc
140     */
141 fabian 1.13 if ((unsigned int) *i < 32 && !strchr ("\002\003\026\037", *i))
142 fabian 1.4 *i = '?';
143     } else { /* string == NULL && e->u.string != NULL */
144 segfault 1.1 nfree(e->u.string);
145     e->u.string = NULL;
146 fabian 1.4 }
147 fabian 1.7 if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED))) {
148     if (e->type != &USERENTRY_INFO || share_greet)
149 fabian 1.12 shareout(NULL, "c %s %s %s\n", e->type->name, u->handle,
150     e->u.string ? e->u.string : "");
151 segfault 1.1 }
152     return 1;
153     }
154    
155     int def_gotshare(struct userrec *u, struct user_entry *e,
156     char *data, int idx)
157     {
158     putlog(LOG_CMDS, "*", "%s: change %s %s", dcc[idx].nick, e->type->name,
159     u->handle);
160     return e->type->set(u, e, data);
161     }
162    
163     int def_tcl_get(Tcl_Interp * interp, struct userrec *u,
164     struct user_entry *e, int argc, char **argv)
165     {
166     Tcl_AppendResult(interp, e->u.string, NULL);
167     return TCL_OK;
168     }
169    
170     int def_tcl_set(Tcl_Interp * irp, struct userrec *u,
171     struct user_entry *e, int argc, char **argv)
172     {
173     BADARGS(4, 4, " handle type setting");
174     e->type->set(u, e, argv[3]);
175     return TCL_OK;
176     }
177    
178     int def_expmem(struct user_entry *e)
179     {
180     return strlen(e->u.string) + 1;
181     }
182    
183     void def_display(int idx, struct user_entry *e)
184     {
185     dprintf(idx, " %s: %s\n", e->type->name, e->u.string);
186     }
187    
188     int def_dupuser(struct userrec *new, struct userrec *old,
189     struct user_entry *e)
190     {
191     return set_user(e->type, new, e->u.string);
192     }
193    
194     static void comment_display(int idx, struct user_entry *e)
195     {
196     if (dcc[idx].user && (dcc[idx].user->flags & USER_MASTER))
197     dprintf(idx, " COMMENT: %.70s\n", e->u.string);
198     }
199    
200     struct user_entry_type USERENTRY_COMMENT =
201     {
202     0, /* always 0 ;) */
203     def_gotshare,
204     def_dupuser,
205     def_unpack,
206     def_pack,
207     def_write_userfile,
208     def_kill,
209     def_get,
210     def_set,
211     def_tcl_get,
212     def_tcl_set,
213     def_expmem,
214     comment_display,
215     "COMMENT"
216     };
217    
218     struct user_entry_type USERENTRY_INFO =
219     {
220     0, /* always 0 ;) */
221     def_gotshare,
222     def_dupuser,
223     def_unpack,
224     def_pack,
225     def_write_userfile,
226     def_kill,
227     def_get,
228     def_set,
229     def_tcl_get,
230     def_tcl_set,
231     def_expmem,
232     def_display,
233     "INFO"
234     };
235    
236     int pass_set(struct userrec *u, struct user_entry *e, void *buf)
237     {
238     char new[32];
239     register char *pass = buf;
240    
241     if (e->u.extra)
242     nfree(e->u.extra);
243     if (!pass || !pass[0] || (pass[0] == '-'))
244     e->u.extra = NULL;
245     else {
246     unsigned char *p = (unsigned char *) pass;
247    
248     if (strlen(pass) > 15)
249     pass[15] = 0;
250     while (*p) {
251     if ((*p <= 32) || (*p == 127))
252     *p = '?';
253     p++;
254     }
255     if ((u->flags & USER_BOT) || (pass[0] == '+'))
256     strcpy(new, pass);
257     else
258     encrypt_pass(pass, new);
259     e->u.extra = user_malloc(strlen(new) + 1);
260     strcpy(e->u.extra, new);
261     }
262     if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
263     shareout(NULL, "c PASS %s %s\n", u->handle, pass ? pass : "");
264     return 1;
265     }
266    
267     static int pass_tcl_set(Tcl_Interp * irp, struct userrec *u,
268     struct user_entry *e, int argc, char **argv)
269     {
270     BADARGS(3, 4, " handle PASS ?newpass?");
271     pass_set(u, e, argv[3]);
272     return TCL_OK;
273     }
274    
275     struct user_entry_type USERENTRY_PASS =
276     {
277     0,
278     def_gotshare,
279     0,
280     def_unpack,
281     def_pack,
282     def_write_userfile,
283     def_kill,
284     def_get,
285     pass_set,
286     def_tcl_get,
287     pass_tcl_set,
288     def_expmem,
289     0,
290     "PASS"
291     };
292    
293     static int laston_unpack(struct userrec *u, struct user_entry *e)
294     {
295 fabian 1.3 char *par, *arg;
296     struct laston_info *li;
297    
298     par = e->u.list->extra;
299     arg = newsplit (&par);
300     if (!par[0])
301     par = "???";
302     li = user_malloc(sizeof(struct laston_info));
303     li->lastonplace = user_malloc(strlen(par) + 1);
304     li->laston = atoi(arg);
305     strcpy(li->lastonplace, par);
306     list_type_kill(e->u.list);
307     e->u.extra = li;
308 segfault 1.1 return 1;
309     }
310    
311     static int laston_pack(struct userrec *u, struct user_entry *e)
312     {
313 fabian 1.3 char work[1024];
314     struct laston_info *li;
315     int l;
316    
317     li = (struct laston_info *) e->u.extra;
318     l = sprintf(work, "%lu %s", li->laston, li->lastonplace);
319     e->u.list = user_malloc(sizeof(struct list_type));
320     e->u.list->next = NULL;
321     e->u.list->extra = user_malloc(l + 1);
322     strcpy(e->u.list->extra, work);
323     nfree(li->lastonplace);
324     nfree(li);
325 segfault 1.1 return 1;
326     }
327    
328     static int laston_write_userfile(FILE * f,
329     struct userrec *u,
330     struct user_entry *e)
331     {
332     struct laston_info *li = (struct laston_info *) e->u.extra;
333    
334     if (fprintf(f, "--LASTON %lu %s\n", li->laston,
335     li->lastonplace ? li->lastonplace : "") == EOF)
336     return 0;
337     return 1;
338     }
339    
340     static int laston_kill(struct user_entry *e)
341     {
342     if (((struct laston_info *) (e->u.extra))->lastonplace)
343     nfree(((struct laston_info *) (e->u.extra))->lastonplace);
344     nfree(e->u.extra);
345     nfree(e);
346     return 1;
347     }
348    
349     static int laston_set(struct userrec *u, struct user_entry *e, void *buf)
350     {
351 fabian 1.3 struct laston_info *li = (struct laston_info *) e->u.extra;
352    
353     if (li != buf) {
354     if (li) {
355     nfree(li->lastonplace);
356     nfree(li);
357     }
358    
359     li = e->u.extra = buf;
360 segfault 1.1 }
361 fabian 1.3 /* donut share laston info */
362 segfault 1.1 return 1;
363     }
364    
365     static int laston_tcl_get(Tcl_Interp * irp, struct userrec *u,
366     struct user_entry *e, int argc, char **argv)
367     {
368 fabian 1.3 struct laston_info *li = (struct laston_info *) e->u.extra;
369 segfault 1.1 char number[20];
370     struct chanuserrec *cr;
371    
372     BADARGS(3, 4, " handle LASTON ?channel?");
373     if (argc == 4) {
374     for (cr = u->chanrec; cr; cr = cr->next)
375     if (!rfc_casecmp(cr->channel, argv[3])) {
376     Tcl_AppendResult(irp, int_to_base10(cr->laston), NULL);
377     break;
378     }
379     if (!cr)
380     Tcl_AppendResult(irp, "0", NULL);
381     } else {
382     sprintf(number, "%lu ", li->laston);
383     Tcl_AppendResult(irp, number, li->lastonplace, NULL);
384     }
385     return TCL_OK;
386     }
387    
388     static int laston_tcl_set(Tcl_Interp * irp, struct userrec *u,
389     struct user_entry *e, int argc, char **argv)
390     {
391     struct laston_info *li;
392     struct chanuserrec *cr;
393    
394 fabian 1.5 BADARGS(4, 5, " handle LASTON time ?place?");
395    
396     if ((argc == 5) && argv[4][0] && strchr(CHANMETA, argv[4][0])) {
397     /* Search for matching channel */
398     for (cr = u->chanrec; cr; cr = cr->next)
399     if (!rfc_casecmp(cr->channel, argv[4])) {
400     cr->laston = atoi(argv[3]);
401     break;
402     }
403     }
404     /* Save globally */
405     li = user_malloc(sizeof(struct laston_info));
406    
407 segfault 1.1 if (argc == 5) {
408     li->lastonplace = user_malloc(strlen(argv[4]) + 1);
409     strcpy(li->lastonplace, argv[4]);
410     } else {
411 fabian 1.5 li->lastonplace = user_malloc(1);
412     li->lastonplace[0] = 0;
413 segfault 1.1 }
414 fabian 1.5 li->laston = atoi(argv[3]);
415     set_user(&USERENTRY_LASTON, u, li);
416 segfault 1.1 return TCL_OK;
417     }
418    
419     static int laston_expmem(struct user_entry *e)
420     {
421     return sizeof(struct laston_info) +
422 fabian 1.3 strlen(((struct laston_info *) (e->u.extra))->lastonplace) + 1;
423 segfault 1.1 }
424    
425     static int laston_dupuser(struct userrec *new, struct userrec *old,
426     struct user_entry *e)
427     {
428     struct laston_info *li = e->u.extra, *li2;
429    
430     if (li) {
431     li2 = user_malloc(sizeof(struct laston_info));
432    
433     li2->laston = li->laston;
434     li2->lastonplace = user_malloc(strlen(li->lastonplace) + 1);
435     strcpy(li2->lastonplace, li->lastonplace);
436     return set_user(&USERENTRY_LASTON, new, li2);
437     }
438     return 0;
439     }
440    
441     struct user_entry_type USERENTRY_LASTON =
442     {
443     0, /* always 0 ;) */
444     0,
445     laston_dupuser,
446     laston_unpack,
447     laston_pack,
448     laston_write_userfile,
449     laston_kill,
450     def_get,
451     laston_set,
452     laston_tcl_get,
453     laston_tcl_set,
454     laston_expmem,
455     0,
456     "LASTON"
457     };
458    
459     static int botaddr_unpack(struct userrec *u, struct user_entry *e)
460     {
461 fabian 1.3 char *p, *q;
462     struct bot_addr *bi = user_malloc(sizeof(struct bot_addr));
463    
464 fabian 1.14 egg_bzero(bi, sizeof(struct bot_addr));
465 segfault 1.1
466 fabian 1.3 if (!(q = strchr ((p = e->u.list->extra), ':'))) {
467 fabian 1.14 bi->address = user_malloc(strlen (p) + 1);
468 fabian 1.3 strcpy (bi->address, p);
469     } else {
470     bi->address = user_malloc((q - p) + 1);
471     strncpy(bi->address, p, q - p);
472     bi->address[q - p] = 0;
473     q++;
474     bi->telnet_port = atoi(q);
475     if ((q = strchr(q, '/')))
476     bi->relay_port = atoi(q + 1);
477 segfault 1.1 }
478 fabian 1.3 if (!bi->telnet_port)
479     bi->telnet_port = 3333;
480     if (!bi->relay_port)
481     bi->relay_port = bi->telnet_port;
482     list_type_kill(e->u.list);
483     e->u.extra = bi;
484 segfault 1.1 return 1;
485     }
486    
487     static int botaddr_pack(struct userrec *u, struct user_entry *e)
488     {
489 fabian 1.3 char work[1024];
490     struct bot_addr *bi;
491     int l;
492    
493     bi = (struct bot_addr *) e->u.extra;
494     l = simple_sprintf(work, "%s:%u/%u", bi->address, bi->telnet_port,
495     bi->relay_port);
496     e->u.list = user_malloc(sizeof(struct list_type));
497     e->u.list->next = NULL;
498     e->u.list->extra = user_malloc(l + 1);
499     strcpy(e->u.list->extra, work);
500     nfree(bi->address);
501     nfree(bi);
502 segfault 1.1 return 1;
503     }
504    
505     static int botaddr_kill(struct user_entry *e)
506     {
507     nfree(((struct bot_addr *) (e->u.extra))->address);
508     nfree(e->u.extra);
509     nfree(e);
510     return 1;
511     }
512    
513 fabian 1.12 static int botaddr_write_userfile(FILE *f, struct userrec *u,
514     struct user_entry *e)
515 segfault 1.1 {
516     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
517    
518 fabian 1.3 if (fprintf(f, "--%s %s:%u/%u\n", e->type->name, bi->address,
519 segfault 1.1 bi->telnet_port, bi->relay_port) == EOF)
520     return 0;
521     return 1;
522     }
523    
524     static int botaddr_set(struct userrec *u, struct user_entry *e, void *buf)
525     {
526 fabian 1.3 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
527    
528     if (!bi && !buf)
529     return 1;
530     if (bi != buf) {
531     if (bi) {
532 fabian 1.8 nfree(bi->address);
533     nfree(bi);
534 fabian 1.3 }
535     bi = e->u.extra = buf;
536     }
537     if (bi && !noshare && !(u->flags & USER_UNSHARED)) {
538     shareout(NULL, "c BOTADDR %s %s %d %d\n", u->handle,
539     bi->address, bi->telnet_port, bi->relay_port);
540 segfault 1.1 }
541     return 1;
542     }
543    
544 fabian 1.12 static int botaddr_tcl_get(Tcl_Interp *interp, struct userrec *u,
545 segfault 1.1 struct user_entry *e, int argc, char **argv)
546     {
547     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
548     char number[20];
549    
550     sprintf(number, " %d", bi->telnet_port);
551     Tcl_AppendResult(interp, bi->address, number, NULL);
552     sprintf(number, " %d", bi->relay_port);
553     Tcl_AppendResult(interp, number, NULL);
554     return TCL_OK;
555     }
556    
557 fabian 1.12 static int botaddr_tcl_set(Tcl_Interp *irp, struct userrec *u,
558 segfault 1.1 struct user_entry *e, int argc, char **argv)
559     {
560     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
561    
562     BADARGS(4, 6, " handle type address ?telnetport ?relayport??");
563     if (u->flags & USER_BOT) {
564 fabian 1.12 /* Silently ignore for users */
565 fabian 1.3 if (!bi) {
566 segfault 1.1 bi = user_malloc(sizeof(struct bot_addr));
567 fabian 1.14 egg_bzero(bi, sizeof (struct bot_addr));
568 fabian 1.3 } else {
569 segfault 1.1 nfree(bi->address);
570 fabian 1.3 }
571 segfault 1.1 bi->address = user_malloc(strlen(argv[3]) + 1);
572     strcpy(bi->address, argv[3]);
573     if (argc > 4)
574     bi->telnet_port = atoi(argv[4]);
575     if (argc > 5)
576     bi->relay_port = atoi(argv[5]);
577 fabian 1.3 if (!bi->telnet_port)
578     bi->telnet_port = 3333;
579     if (!bi->relay_port)
580     bi->relay_port = bi->telnet_port;
581 segfault 1.1 botaddr_set(u, e, bi);
582     }
583     return TCL_OK;
584     }
585    
586     static int botaddr_expmem(struct user_entry *e)
587     {
588     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
589    
590     return strlen(bi->address) + 1 + sizeof(struct bot_addr);
591     }
592    
593     static void botaddr_display(int idx, struct user_entry *e)
594     {
595     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
596    
597     dprintf(idx, " ADDRESS: %.70s\n", bi->address);
598     dprintf(idx, " telnet: %d, relay: %d\n", bi->telnet_port, bi->relay_port);
599     }
600    
601     static int botaddr_gotshare(struct userrec *u, struct user_entry *e,
602     char *buf, int idx)
603     {
604     struct bot_addr *bi = user_malloc(sizeof(struct bot_addr));
605 fabian 1.3 char *arg;
606 segfault 1.1
607 fabian 1.14 egg_bzero(bi, sizeof(struct bot_addr));
608 fabian 1.3 arg = newsplit(&buf);
609     bi->address = user_malloc(strlen(arg) + 1);
610     strcpy(bi->address, arg);
611     arg = newsplit(&buf);
612     bi->telnet_port = atoi(arg);
613     bi->relay_port = atoi(buf);
614     if (!bi->telnet_port)
615 segfault 1.1 bi->telnet_port = 3333;
616 fabian 1.3 if (!bi->relay_port)
617     bi->relay_port = bi->telnet_port;
618 segfault 1.1 if (!(dcc[idx].status & STAT_GETTING))
619     putlog(LOG_CMDS, "*", "%s: change botaddr %s", dcc[idx].nick,
620     u->handle);
621     return botaddr_set(u, e, bi);
622     }
623    
624     static int botaddr_dupuser(struct userrec *new, struct userrec *old,
625     struct user_entry *e)
626     {
627     if (old->flags & USER_BOT) {
628     struct bot_addr *bi = e->u.extra, *bi2;
629    
630     if (bi) {
631     bi2 = user_malloc(sizeof(struct bot_addr));
632    
633     bi2->telnet_port = bi->telnet_port;
634     bi2->relay_port = bi->relay_port;
635     bi2->address = user_malloc(strlen(bi->address) + 1);
636     strcpy(bi2->address, bi->address);
637     return set_user(&USERENTRY_BOTADDR, new, bi2);
638     }
639     }
640     return 0;
641     }
642    
643     struct user_entry_type USERENTRY_BOTADDR =
644     {
645     0, /* always 0 ;) */
646     botaddr_gotshare,
647     botaddr_dupuser,
648     botaddr_unpack,
649     botaddr_pack,
650     botaddr_write_userfile,
651     botaddr_kill,
652     def_get,
653     botaddr_set,
654     botaddr_tcl_get,
655     botaddr_tcl_set,
656     botaddr_expmem,
657     botaddr_display,
658     "BOTADDR"
659     };
660    
661 fabian 1.2 int xtra_set(struct userrec *u, struct user_entry *e, void *buf)
662 segfault 1.1 {
663 fabian 1.3 struct xtra_key *curr, *old = NULL, *new = buf;
664 segfault 1.1
665 fabian 1.3 for (curr = e->u.extra; curr; curr = curr->next) {
666 fabian 1.14 if (curr->key && !egg_strcasecmp(curr->key, new->key)) {
667 fabian 1.3 old = curr;
668 segfault 1.1 break;
669     }
670     }
671 fabian 1.3 if (!old && (!new->data || !new->data[0])) {
672 fabian 1.12 /* Delete non-existant entry -- doh ++rtc */
673 fabian 1.3 nfree(new->key);
674     if (new->data)
675     nfree(new->data);
676     nfree(new);
677     return TCL_OK;
678 segfault 1.1 }
679 fabian 1.3
680 fabian 1.12 /* We will possibly free new below, so let's send the information
681     * to the botnet now
682     */
683 segfault 1.1 if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
684 fabian 1.3 shareout(NULL, "c XTRA %s %s %s\n", u->handle, new->key,
685     new->data ? new->data : "");
686     if ((old && old != new) || !new->data || !new->data[0]) {
687     list_delete((struct list_type **) (&e->u.extra),
688     (struct list_type *) old);
689     nfree(old->key);
690     nfree(old->data);
691     nfree(old);
692     }
693 fabian 1.7 if (old != new && new->data) {
694     if (new->data[0])
695 fabian 1.3 list_insert((&e->u.extra), new) /* do not add a ';' here */
696 guppy 1.19 } else {
697     if (new->data)
698 fabian 1.7 nfree(new->data);
699 guppy 1.19 nfree(new->key);
700     nfree(new);
701 segfault 1.1 }
702     return TCL_OK;
703     }
704    
705     static int xtra_tcl_set(Tcl_Interp * irp, struct userrec *u,
706     struct user_entry *e, int argc, char **argv)
707     {
708 fabian 1.3 struct xtra_key *xk;
709     int l;
710    
711 segfault 1.1 BADARGS(4, 5, " handle type key ?value?");
712 fabian 1.3 xk = user_malloc(sizeof(struct xtra_key));
713     l = strlen(argv[3]);
714 fabian 1.14 egg_bzero(xk, sizeof (struct xtra_key));
715 fabian 1.3 if (l > 500)
716     l = 500;
717     xk->key = user_malloc(l + 1);
718 guppy 1.18 strncpyz(xk->key, argv[3], l + 1);
719 segfault 1.1
720 fabian 1.5 if (argc == 5) {
721 fabian 1.3 int k = strlen(argv[4]);
722 fabian 1.12
723 segfault 1.1 if (k > 500 - l)
724     k = 500 - l;
725 fabian 1.3 xk->data = user_malloc(k + 1);
726 guppy 1.18 strncpyz(xk->data, argv[4], k + 1);
727 segfault 1.1 }
728 fabian 1.3 xtra_set(u, e, xk);
729 segfault 1.1 return TCL_OK;
730     }
731    
732     int xtra_unpack(struct userrec *u, struct user_entry *e)
733     {
734 fabian 1.3 struct list_type *curr, *head;
735     struct xtra_key *t;
736     char *key, *data;
737    
738     head = curr = e->u.list;
739     e->u.extra = NULL;
740     while (curr) {
741     t = user_malloc(sizeof(struct xtra_key));
742    
743     data = curr->extra;
744     key = newsplit(&data);
745     if (data[0]) {
746     t->key = user_malloc(strlen(key) + 1);
747     strcpy(t->key, key);
748     t->data = user_malloc(strlen(data) + 1);
749     strcpy(t->data, data);
750 segfault 1.1 list_insert((&e->u.extra), t);
751     }
752 fabian 1.3 curr = curr->next;
753 segfault 1.1 }
754 fabian 1.3 list_type_kill(head);
755 segfault 1.1 return 1;
756     }
757    
758     static int xtra_pack(struct userrec *u, struct user_entry *e)
759     {
760 fabian 1.3 struct list_type *t;
761     struct xtra_key *curr, *next;
762    
763     curr = e->u.extra;
764     e->u.list = NULL;
765     while (curr) {
766     t = user_malloc(sizeof(struct list_type));
767     t->extra = user_malloc(strlen(curr->key) + strlen(curr->data) + 4);
768     sprintf(t->extra, "%s %s", curr->key, curr->data);
769     list_insert((&e->u.list), t);
770     next = curr->next;
771     nfree(curr->key);
772     nfree(curr->data);
773     nfree(curr);
774     curr = next;
775 segfault 1.1 }
776     return 1;
777     }
778    
779     static void xtra_display(int idx, struct user_entry *e)
780     {
781     int code, lc, j;
782     struct xtra_key *xk;
783     char **list;
784    
785     code = Tcl_SplitList(interp, whois_fields, &lc, &list);
786     if (code == TCL_ERROR)
787     return;
788 fabian 1.12 /* Scan thru xtra field, searching for matches */
789 segfault 1.1 for (xk = e->u.extra; xk; xk = xk->next) {
790 fabian 1.12 /* Ok, it's a valid xtra field entry */
791 segfault 1.1 for (j = 0; j < lc; j++) {
792 fabian 1.15 if (!egg_strcasecmp(list[j], xk->key))
793 segfault 1.1 dprintf(idx, " %s: %s\n", xk->key, xk->data);
794     }
795     }
796 fabian 1.6 Tcl_Free((char *) list);
797 segfault 1.1 }
798    
799     static int xtra_gotshare(struct userrec *u, struct user_entry *e,
800     char *buf, int idx)
801     {
802 fabian 1.3 char *arg;
803     struct xtra_key *xk;
804     int l;
805 segfault 1.1
806 fabian 1.3 arg = newsplit (&buf);
807     if (!arg[0])
808     return 1;
809    
810     xk = user_malloc (sizeof(struct xtra_key));
811 fabian 1.14 egg_bzero(xk, sizeof(struct xtra_key));
812 fabian 1.3 l = strlen(arg);
813     if (l > 500)
814     l = 500;
815     xk->key = user_malloc(l + 1);
816 guppy 1.18 strncpyz(xk->key, arg, l + 1);
817 segfault 1.1
818 fabian 1.3 if (buf[0]) {
819     int k = strlen(buf);
820 segfault 1.1
821     if (k > 500 - l)
822 fabian 1.3 k = 500 - l;
823 segfault 1.1 xk->data = user_malloc(k + 1);
824 guppy 1.18 strncpyz(xk->data, buf, k + 1);
825 segfault 1.1 }
826 fabian 1.3 xtra_set(u, e, xk);
827 segfault 1.1 return 1;
828     }
829    
830     static int xtra_dupuser(struct userrec *new, struct userrec *old,
831     struct user_entry *e)
832     {
833     struct xtra_key *x1, *x2;
834    
835     for (x1 = e->u.extra; x1; x1 = x1->next) {
836     x2 = user_malloc(sizeof(struct xtra_key));
837    
838     x2->key = user_malloc(strlen(x1->key) + 1);
839     strcpy(x2->key, x1->key);
840     x2->data = user_malloc(strlen(x1->data) + 1);
841     strcpy(x2->data, x1->data);
842     set_user(&USERENTRY_XTRA, new, x2);
843     }
844     return 1;
845     }
846    
847 fabian 1.12 static int xtra_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
848 segfault 1.1 {
849     struct xtra_key *x;
850    
851     for (x = e->u.extra; x; x = x->next)
852     if (fprintf(f, "--XTRA %s %s\n", x->key, x->data) == EOF)
853     return 0;
854     return 1;
855     }
856    
857     int xtra_kill(struct user_entry *e)
858     {
859     struct xtra_key *x, *y;
860    
861     for (x = e->u.extra; x; x = y) {
862     y = x->next;
863     nfree(x->key);
864     nfree(x->data);
865     nfree(x);
866     }
867     nfree(e);
868     return 1;
869     }
870    
871 fabian 1.12 static int xtra_tcl_get(Tcl_Interp *irp, struct userrec *u,
872 segfault 1.1 struct user_entry *e, int argc, char **argv)
873     {
874     struct xtra_key *x;
875    
876     BADARGS(3, 4, " handle XTRA ?key?");
877     if (argc == 4) {
878     for (x = e->u.extra; x; x = x->next)
879 fabian 1.14 if (!egg_strcasecmp(argv[3], x->key)) {
880 segfault 1.1 Tcl_AppendResult(irp, x->data, NULL);
881     return TCL_OK;
882     }
883     return TCL_OK;
884     }
885     for (x = e->u.extra; x; x = x->next) {
886     char *p, *list[2];
887    
888     list[0] = x->key;
889     list[1] = x->data;
890     p = Tcl_Merge(2, list);
891     Tcl_AppendElement(irp, p);
892 fabian 1.6 Tcl_Free((char *) p);
893 segfault 1.1 }
894     return TCL_OK;
895     }
896    
897     static int xtra_expmem(struct user_entry *e)
898     {
899     struct xtra_key *x;
900     int tot = 0;
901    
902     for (x = e->u.extra; x; x = x->next) {
903     tot += sizeof(struct xtra_key);
904    
905     tot += strlen(x->key) + 1;
906     tot += strlen(x->data) + 1;
907     }
908     return tot;
909     }
910    
911     struct user_entry_type USERENTRY_XTRA =
912     {
913     0,
914     xtra_gotshare,
915     xtra_dupuser,
916     xtra_unpack,
917     xtra_pack,
918     xtra_write_userfile,
919     xtra_kill,
920     def_get,
921     xtra_set,
922     xtra_tcl_get,
923     xtra_tcl_set,
924     xtra_expmem,
925     xtra_display,
926     "XTRA"
927     };
928    
929     static int hosts_dupuser(struct userrec *new, struct userrec *old,
930     struct user_entry *e)
931     {
932     struct list_type *h;
933    
934     for (h = e->u.extra; h; h = h->next)
935     set_user(&USERENTRY_HOSTS, new, h->extra);
936     return 1;
937     }
938    
939     static int hosts_null(struct userrec *u, struct user_entry *e)
940     {
941     return 1;
942     }
943    
944 fabian 1.12 static int hosts_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
945 segfault 1.1 {
946     struct list_type *h;
947    
948     for (h = e->u.extra; h; h = h->next)
949     if (fprintf(f, "--HOSTS %s\n", h->extra) == EOF)
950     return 0;
951     return 1;
952     }
953    
954     static int hosts_kill(struct user_entry *e)
955     {
956     list_type_kill(e->u.list);
957     nfree(e);
958     return 1;
959     }
960    
961     static int hosts_expmem(struct user_entry *e)
962     {
963     return list_type_expmem(e->u.list);
964     }
965    
966     static void hosts_display(int idx, struct user_entry *e)
967     {
968     char s[1024];
969     struct list_type *q;
970    
971     s[0] = 0;
972     strcpy(s, " HOSTS: ");
973     for (q = e->u.list; q; q = q->next) {
974     if (s[0] && !s[9])
975     strcat(s, q->extra);
976     else if (!s[0])
977 guppy 1.17 sprintf(s, " %s", q->extra);
978 segfault 1.1 else {
979     if (strlen(s) + strlen(q->extra) + 2 > 65) {
980     dprintf(idx, "%s\n", s);
981 guppy 1.17 sprintf(s, " %s", q->extra);
982 segfault 1.1 } else {
983     strcat(s, ", ");
984     strcat(s, q->extra);
985     }
986     }
987     }
988     if (s[0])
989     dprintf(idx, "%s\n", s);
990     }
991    
992     static int hosts_set(struct userrec *u, struct user_entry *e, void *buf)
993     {
994 fabian 1.14 if (!buf || !egg_strcasecmp(buf, "none")) {
995 fabian 1.12 /* When the bot crashes, it's in this part, not in the 'else' part */
996 fabian 1.3 list_type_kill(e->u.list);
997     e->u.list = NULL;
998 segfault 1.1 } else {
999     char *host = buf, *p = strchr(host, ',');
1000     struct list_type **t;
1001    
1002 fabian 1.12 /* Can't have ,'s in hostmasks */
1003 segfault 1.1 while (p) {
1004     *p = '?';
1005     p = strchr(host, ',');
1006     }
1007     /* fred1: check for redundant hostmasks with
1008     * controversial "superpenis" algorithm ;) */
1009     /* I'm surprised Raistlin hasn't gotten involved in this controversy */
1010     t = &(e->u.list);
1011     while (*t) {
1012     if (wild_match(host, (*t)->extra)) {
1013     struct list_type *u;
1014    
1015     u = *t;
1016     *t = (*t)->next;
1017     if (u->extra)
1018     nfree(u->extra);
1019     nfree(u);
1020     } else
1021     t = &((*t)->next);
1022     }
1023     *t = user_malloc(sizeof(struct list_type));
1024    
1025     (*t)->next = NULL;
1026     (*t)->extra = user_malloc(strlen(host) + 1);
1027     strcpy((*t)->extra, host);
1028     }
1029     return 1;
1030     }
1031    
1032 fabian 1.12 static int hosts_tcl_get(Tcl_Interp *irp, struct userrec *u,
1033 segfault 1.1 struct user_entry *e, int argc, char **argv)
1034     {
1035     struct list_type *x;
1036    
1037     BADARGS(3, 3, " handle HOSTS");
1038     for (x = e->u.list; x; x = x->next)
1039     Tcl_AppendElement(irp, x->extra);
1040     return TCL_OK;
1041     }
1042    
1043     static int hosts_tcl_set(Tcl_Interp * irp, struct userrec *u,
1044     struct user_entry *e, int argc, char **argv)
1045     {
1046     BADARGS(3, 4, " handle HOSTS ?host?");
1047     if (argc == 4)
1048     addhost_by_handle(u->handle, argv[3]);
1049 fabian 1.12 else
1050 segfault 1.1 addhost_by_handle(u->handle, "none"); /* drummer */
1051     return TCL_OK;
1052     }
1053    
1054     static int hosts_gotshare(struct userrec *u, struct user_entry *e,
1055     char *buf, int idx)
1056     {
1057     /* doh, try to be too clever and it bites your butt */
1058     return 0;
1059     }
1060    
1061     struct user_entry_type USERENTRY_HOSTS =
1062     {
1063     0,
1064     hosts_gotshare,
1065     hosts_dupuser,
1066     hosts_null,
1067     hosts_null,
1068     hosts_write_userfile,
1069     hosts_kill,
1070     def_get,
1071     hosts_set,
1072     hosts_tcl_get,
1073     hosts_tcl_set,
1074     hosts_expmem,
1075     hosts_display,
1076     "HOSTS"
1077     };
1078    
1079     int list_append(struct list_type **h, struct list_type *i)
1080     {
1081     for (; *h; h = &((*h)->next));
1082     *h = i;
1083     return 1;
1084     }
1085    
1086     int list_delete(struct list_type **h, struct list_type *i)
1087     {
1088     for (; *h; h = &((*h)->next))
1089     if (*h == i) {
1090     *h = i->next;
1091     return 1;
1092     }
1093     return 0;
1094     }
1095    
1096     int list_contains(struct list_type *h, struct list_type *i)
1097     {
1098     for (; h; h = h->next)
1099     if (h == i) {
1100     return 1;
1101     }
1102     return 0;
1103     }
1104    
1105     int add_entry_type(struct user_entry_type *type)
1106     {
1107     struct userrec *u;
1108    
1109     list_insert(&entry_type_list, type);
1110     for (u = userlist; u; u = u->next) {
1111     struct user_entry *e = find_user_entry(type, u);
1112    
1113     if (e && e->name) {
1114     e->type = type;
1115     e->type->unpack(u, e);
1116     nfree(e->name);
1117     e->name = NULL;
1118     }
1119     }
1120     return 1;
1121     }
1122    
1123     int del_entry_type(struct user_entry_type *type)
1124     {
1125     struct userrec *u;
1126    
1127     for (u = userlist; u; u = u->next) {
1128     struct user_entry *e = find_user_entry(type, u);
1129    
1130     if (e && !e->name) {
1131     e->type->pack(u, e);
1132     e->name = user_malloc(strlen(e->type->name) + 1);
1133     strcpy(e->name, e->type->name);
1134     e->type = NULL;
1135     }
1136     }
1137     return list_delete((struct list_type **) &entry_type_list,
1138     (struct list_type *) type);
1139     }
1140    
1141     struct user_entry_type *find_entry_type(char *name)
1142     {
1143     struct user_entry_type *p;
1144    
1145     for (p = entry_type_list; p; p = p->next) {
1146 fabian 1.14 if (!egg_strcasecmp(name, p->name))
1147 segfault 1.1 return p;
1148     }
1149     return NULL;
1150     }
1151    
1152     struct user_entry *find_user_entry(struct user_entry_type *et,
1153     struct userrec *u)
1154     {
1155     struct user_entry **e, *t;
1156    
1157     for (e = &(u->entries); *e; e = &((*e)->next)) {
1158     if (((*e)->type == et) ||
1159 fabian 1.14 ((*e)->name && !egg_strcasecmp((*e)->name, et->name))) {
1160 segfault 1.1 t = *e;
1161     *e = t->next;
1162     t->next = u->entries;
1163     u->entries = t;
1164     return t;
1165     }
1166     }
1167     return NULL;
1168     }
1169    
1170     void *get_user(struct user_entry_type *et, struct userrec *u)
1171     {
1172     struct user_entry *e;
1173    
1174     if (u && (e = find_user_entry(et, u)))
1175     return et->get(u, e);
1176     return 0;
1177     }
1178    
1179     int set_user(struct user_entry_type *et, struct userrec *u, void *d)
1180     {
1181     struct user_entry *e;
1182     int r;
1183    
1184     if (!u || !et)
1185     return 0;
1186    
1187     if (!(e = find_user_entry(et, u))) {
1188     e = user_malloc(sizeof(struct user_entry));
1189    
1190     e->type = et;
1191     e->name = NULL;
1192     e->u.list = NULL;
1193     list_insert((&(u->entries)), e);
1194     }
1195     r = et->set(u, e, d);
1196     if (!e->u.list) {
1197     list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
1198     nfree(e);
1199     }
1200     return r;
1201     }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23