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

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

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


Revision 1.1.1.1 - (hide annotations) (download) (as text) (vendor branch)
Mon Jul 26 21:11:06 2010 UTC (8 years, 9 months ago) by simple
Branch: eggheads
CVS Tags: v1
Changes since 1.1: +0 -0 lines
File MIME type: text/x-chdr
Imported Eggdrop 1.6.20

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23