/[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.4 - (hide annotations) (download) (as text)
Mon Nov 1 22:38:34 2010 UTC (8 years, 6 months ago) by pseudo
Branch: MAIN
Branch point for: gettext
Changes since 1.3: +30 -29 lines
File MIME type: text/x-chdr
Made it possible to specify ssl independently for telnet and user ports when modifying bot addresses.
Changed the syntax of .chaddr and .+bot to use space as a port separator instead of ':'.
Changed the syntax of server list entries to enclose literal IPv6 addresses in square brackets, instead of using a comma to separate the port.

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23