/[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.5 - (hide annotations) (download) (as text)
Thu Oct 2 19:27:43 2014 UTC (4 years, 7 months ago) by thommey
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +1 -5 lines
File MIME type: text/x-chdr
Remove length limit of info line. Fix stripcodes modifying the Tcl object in-place. Only permanent owners can
delete owners.

1 simple 1.1 /*
2     * userent.c -- handles:
3     * user-entry handling, new style more versatile.
4     *
5 thommey 1.5 * $Id: userent.c,v 1.4 2010/11/01 22:38:34 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     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 pseudo 1.3 #ifdef TLS
477     if (*q == '+')
478 pseudo 1.4 bi->ssl |= TLS_BOT;
479 pseudo 1.3 #endif
480 simple 1.1 bi->telnet_port = atoi(q);
481     if ((q = strchr(q, '/')))
482 pseudo 1.3 #ifdef TLS
483     {
484     if (q[1] == '+')
485 pseudo 1.4 bi->ssl |= TLS_RELAY;
486 pseudo 1.3 bi->relay_port = atoi(q + 1);
487     }
488     #else
489 simple 1.1 bi->relay_port = atoi(q + 1);
490 pseudo 1.3 #endif
491 simple 1.1 }
492 pseudo 1.2 #ifdef IPV6
493     for (p = bi->address; *p; p++)
494     if (*p == ';')
495     *p = ':';
496     #endif
497 simple 1.1 if (!bi->telnet_port)
498     bi->telnet_port = 3333;
499     if (!bi->relay_port)
500     bi->relay_port = bi->telnet_port;
501     list_type_kill(e->u.list);
502     e->u.extra = bi;
503     return 1;
504     }
505    
506     static int botaddr_pack(struct userrec *u, struct user_entry *e)
507     {
508 pseudo 1.3 char work[1024], *p, *q = work;
509 simple 1.1 struct bot_addr *bi;
510     int l;
511    
512     bi = (struct bot_addr *) e->u.extra;
513 pseudo 1.3 for (p = bi->address; *p; p++)
514 pseudo 1.2 if (*p == ':')
515 pseudo 1.3 *q++ = ';';
516     else
517     *q++ = *p;
518     #ifdef TLS
519 pseudo 1.4 l = simple_sprintf(q, ":%s%u/%s%u", (bi->ssl & TLS_BOT) ? "+" : "",
520     bi->telnet_port, (bi->ssl & TLS_RELAY) ? "+" : "",
521     bi->relay_port);
522     #else
523     l = simple_sprintf(q, ":%u/%u", bi->telnet_port, bi->relay_port);
524 pseudo 1.2 #endif
525 simple 1.1 e->u.list = user_malloc(sizeof(struct list_type));
526     e->u.list->next = NULL;
527     e->u.list->extra = user_malloc(l + 1);
528     strcpy(e->u.list->extra, work);
529     nfree(bi->address);
530     nfree(bi);
531     return 1;
532     }
533    
534     static int botaddr_kill(struct user_entry *e)
535     {
536     nfree(((struct bot_addr *) (e->u.extra))->address);
537     nfree(e->u.extra);
538     nfree(e);
539     return 1;
540     }
541    
542     static int botaddr_write_userfile(FILE *f, struct userrec *u,
543     struct user_entry *e)
544     {
545 pseudo 1.3 int ret = 1;
546     char *p, *q, *addr;
547 simple 1.1 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
548    
549 pseudo 1.3 p = bi->address;
550     addr = user_malloc(strlen(bi->address) + 1);
551     for (q = addr; *p; p++)
552 pseudo 1.2 if (*p == ':')
553 pseudo 1.3 *q++ = ';';
554     else
555     *q++ = *p;
556     *q = 0;
557     #ifdef TLS
558 pseudo 1.4 if (fprintf(f, "--%s %s:%s%u/%s%u\n", e->type->name, addr,
559     (bi->ssl & TLS_BOT) ? "+" : "", bi->telnet_port, (bi->ssl & TLS_RELAY) ?
560     "+" : "", bi->relay_port) == EOF)
561     #else
562 pseudo 1.2 if (fprintf(f, "--%s %s:%u/%u\n", e->type->name, addr,
563 pseudo 1.3 bi->telnet_port, bi->relay_port) == EOF)
564 pseudo 1.4 #endif
565 pseudo 1.3 ret = 0;
566 pseudo 1.2 nfree(addr);
567 pseudo 1.3 return ret;
568 simple 1.1 }
569    
570     static int botaddr_set(struct userrec *u, struct user_entry *e, void *buf)
571     {
572     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
573    
574     if (!bi && !buf)
575     return 1;
576     if (bi != buf) {
577     if (bi) {
578     nfree(bi->address);
579     nfree(bi);
580     }
581     bi = e->u.extra = buf;
582     }
583     if (bi && !noshare && !(u->flags & USER_UNSHARED)) {
584 pseudo 1.3 #ifdef TLS
585 pseudo 1.4 shareout(NULL, "c BOTADDR %s %s %s%d %s%d\n", u->handle, bi->address,
586     (bi->ssl & TLS_BOT) ? "+" : "", bi->telnet_port,
587     (bi->ssl & TLS_RELAY) ? "+" : "", bi->relay_port);
588     #else
589 simple 1.1 shareout(NULL, "c BOTADDR %s %s %d %d\n", u->handle,
590     bi->address, bi->telnet_port, bi->relay_port);
591 pseudo 1.4 #endif
592 simple 1.1 }
593     return 1;
594     }
595    
596     static int botaddr_tcl_get(Tcl_Interp * interp, struct userrec *u,
597     struct user_entry *e, int argc, char **argv)
598     {
599     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
600     char number[20];
601    
602 pseudo 1.3 #ifdef TLS
603 pseudo 1.4 if (bi->ssl & TLS_BOT)
604 pseudo 1.3 sprintf(number, " +%d", bi->telnet_port);
605     else
606     #endif
607 simple 1.1 sprintf(number, " %d", bi->telnet_port);
608     Tcl_AppendResult(interp, bi->address, number, NULL);
609 pseudo 1.3 #ifdef TLS
610 pseudo 1.4 if (bi->ssl & TLS_RELAY)
611 pseudo 1.3 sprintf(number, " +%d", bi->relay_port);
612     else
613     #endif
614 simple 1.1 sprintf(number, " %d", bi->relay_port);
615     Tcl_AppendResult(interp, number, NULL);
616     return TCL_OK;
617     }
618    
619     static int botaddr_tcl_set(Tcl_Interp * irp, struct userrec *u,
620     struct user_entry *e, int argc, char **argv)
621     {
622     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
623    
624     BADARGS(4, 6, " handle type address ?telnetport ?relayport??");
625    
626     if (u->flags & USER_BOT) {
627     /* Silently ignore for users */
628     if (!bi) {
629     bi = user_malloc(sizeof(struct bot_addr));
630     egg_bzero(bi, sizeof(struct bot_addr));
631     } else
632     nfree(bi->address);
633     bi->address = user_malloc(strlen(argv[3]) + 1);
634     strcpy(bi->address, argv[3]);
635     if (argc > 4)
636 pseudo 1.3 #ifdef TLS
637     {
638     if (*argv[4] == '+')
639 pseudo 1.4 bi->ssl |= TLS_BOT;
640 pseudo 1.3 bi->telnet_port = atoi(argv[4]);
641     }
642     #else
643 simple 1.1 bi->telnet_port = atoi(argv[4]);
644 pseudo 1.3 #endif
645 simple 1.1 if (argc > 5)
646 pseudo 1.3 #ifdef TLS
647     {
648     if (*argv[5] == '+')
649 pseudo 1.4 bi->ssl |= TLS_RELAY;
650 pseudo 1.3 bi->relay_port = atoi(argv[5]);
651     }
652     #else
653 simple 1.1 bi->relay_port = atoi(argv[5]);
654 pseudo 1.3 #endif
655 simple 1.1 if (!bi->telnet_port)
656     bi->telnet_port = 3333;
657     if (!bi->relay_port)
658     bi->relay_port = bi->telnet_port;
659     botaddr_set(u, e, bi);
660     }
661     return TCL_OK;
662     }
663    
664     static int botaddr_expmem(struct user_entry *e)
665     {
666     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
667    
668     return strlen(bi->address) + 1 + sizeof(struct bot_addr);
669     }
670    
671     static void botaddr_display(int idx, struct user_entry *e)
672     {
673     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
674    
675     dprintf(idx, " ADDRESS: %.70s\n", bi->address);
676 pseudo 1.3 #ifdef TLS
677 pseudo 1.4 dprintf(idx, " users: %s%d, bots: %s%d\n", (bi->ssl & TLS_RELAY) ? "+" : "",
678     bi->relay_port, (bi->ssl & TLS_BOT) ? "+" : "", bi->telnet_port);
679     #else
680     dprintf(idx, " users: %d, bots: %d\n", bi->relay_port, bi->telnet_port);
681 pseudo 1.3 #endif
682 simple 1.1 }
683    
684     static int botaddr_gotshare(struct userrec *u, struct user_entry *e,
685     char *buf, int idx)
686     {
687     struct bot_addr *bi = user_malloc(sizeof(struct bot_addr));
688     char *arg;
689    
690     egg_bzero(bi, sizeof(struct bot_addr));
691     arg = newsplit(&buf);
692     bi->address = user_malloc(strlen(arg) + 1);
693     strcpy(bi->address, arg);
694     arg = newsplit(&buf);
695 pseudo 1.3 #ifdef TLS
696 pseudo 1.4 if (*arg == '+')
697     bi->ssl |= TLS_BOT;
698     if (*buf == '+')
699     bi->ssl |= TLS_RELAY;
700 pseudo 1.3 #endif
701 simple 1.1 bi->telnet_port = atoi(arg);
702     bi->relay_port = atoi(buf);
703     if (!bi->telnet_port)
704     bi->telnet_port = 3333;
705     if (!bi->relay_port)
706     bi->relay_port = bi->telnet_port;
707     if (!(dcc[idx].status & STAT_GETTING))
708     putlog(LOG_CMDS, "*", "%s: change botaddr %s", dcc[idx].nick, u->handle);
709     return botaddr_set(u, e, bi);
710     }
711    
712     static int botaddr_dupuser(struct userrec *new, struct userrec *old,
713     struct user_entry *e)
714     {
715     if (old->flags & USER_BOT) {
716     struct bot_addr *bi = e->u.extra, *bi2;
717    
718     if (bi) {
719     bi2 = user_malloc(sizeof(struct bot_addr));
720    
721     bi2->telnet_port = bi->telnet_port;
722     bi2->relay_port = bi->relay_port;
723 pseudo 1.3 #ifdef TLS
724     bi2->ssl = bi->ssl;
725     #endif
726 simple 1.1 bi2->address = user_malloc(strlen(bi->address) + 1);
727     strcpy(bi2->address, bi->address);
728     return set_user(&USERENTRY_BOTADDR, new, bi2);
729     }
730     }
731     return 0;
732     }
733    
734     struct user_entry_type USERENTRY_BOTADDR = {
735     0, /* always 0 ;) */
736     botaddr_gotshare,
737     botaddr_dupuser,
738     botaddr_unpack,
739     botaddr_pack,
740     botaddr_write_userfile,
741     botaddr_kill,
742     def_get,
743     botaddr_set,
744     botaddr_tcl_get,
745     botaddr_tcl_set,
746     botaddr_expmem,
747     botaddr_display,
748     "BOTADDR"
749     };
750    
751     int xtra_set(struct userrec *u, struct user_entry *e, void *buf)
752     {
753     struct xtra_key *curr, *old = NULL, *new = buf;
754    
755     for (curr = e->u.extra; curr; curr = curr->next) {
756     if (curr->key && !egg_strcasecmp(curr->key, new->key)) {
757     old = curr;
758     break;
759     }
760     }
761     if (!old && (!new->data || !new->data[0])) {
762     /* Delete non-existant entry -- doh ++rtc */
763     nfree(new->key);
764     if (new->data)
765     nfree(new->data);
766     nfree(new);
767     return TCL_OK;
768     }
769    
770     /* We will possibly free new below, so let's send the information
771     * to the botnet now
772     */
773     if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
774     shareout(NULL, "c XTRA %s %s %s\n", u->handle, new->key,
775     new->data ? new->data : "");
776     if ((old && old != new) || !new->data || !new->data[0]) {
777     egg_list_delete(&e->u.list, (struct list_type *) old);
778     nfree(old->key);
779     nfree(old->data);
780     nfree(old);
781     }
782     if (old != new && new->data) {
783     if (new->data[0])
784     list_insert((&e->u.extra), new) /* do not add a ';' here */
785     } else {
786     if (new->data)
787     nfree(new->data);
788     nfree(new->key);
789     nfree(new);
790     }
791     return TCL_OK;
792     }
793    
794     static int xtra_tcl_set(Tcl_Interp * irp, struct userrec *u,
795     struct user_entry *e, int argc, char **argv)
796     {
797     struct xtra_key *xk;
798     int l;
799    
800     BADARGS(4, 5, " handle type key ?value?");
801    
802     xk = user_malloc(sizeof(struct xtra_key));
803     l = strlen(argv[3]);
804     egg_bzero(xk, sizeof(struct xtra_key));
805     if (l > 500)
806     l = 500;
807     xk->key = user_malloc(l + 1);
808     strncpyz(xk->key, argv[3], l + 1);
809    
810     if (argc == 5) {
811     int k = strlen(argv[4]);
812    
813     if (k > 500 - l)
814     k = 500 - l;
815     xk->data = user_malloc(k + 1);
816     strncpyz(xk->data, argv[4], k + 1);
817     }
818     xtra_set(u, e, xk);
819     return TCL_OK;
820     }
821    
822     int xtra_unpack(struct userrec *u, struct user_entry *e)
823     {
824     struct list_type *curr, *head;
825     struct xtra_key *t;
826     char *key, *data;
827    
828     head = curr = e->u.list;
829     e->u.extra = NULL;
830     while (curr) {
831     t = user_malloc(sizeof(struct xtra_key));
832    
833     data = curr->extra;
834     key = newsplit(&data);
835     if (data[0]) {
836     t->key = user_malloc(strlen(key) + 1);
837     strcpy(t->key, key);
838     t->data = user_malloc(strlen(data) + 1);
839     strcpy(t->data, data);
840     list_insert((&e->u.extra), t);
841     }
842     curr = curr->next;
843     }
844     list_type_kill(head);
845     return 1;
846     }
847    
848     static int xtra_pack(struct userrec *u, struct user_entry *e)
849     {
850     struct list_type *t;
851     struct xtra_key *curr, *next;
852    
853     curr = e->u.extra;
854     e->u.list = NULL;
855     while (curr) {
856     t = user_malloc(sizeof(struct list_type));
857     t->extra = user_malloc(strlen(curr->key) + strlen(curr->data) + 4);
858     sprintf(t->extra, "%s %s", curr->key, curr->data);
859     list_insert((&e->u.list), t);
860     next = curr->next;
861     nfree(curr->key);
862     nfree(curr->data);
863     nfree(curr);
864     curr = next;
865     }
866     return 1;
867     }
868    
869     static void xtra_display(int idx, struct user_entry *e)
870     {
871     int code, lc, j;
872     EGG_CONST char **list;
873     struct xtra_key *xk;
874    
875     code = Tcl_SplitList(interp, whois_fields, &lc, &list);
876     if (code == TCL_ERROR)
877     return;
878     /* Scan thru xtra field, searching for matches */
879     for (xk = e->u.extra; xk; xk = xk->next) {
880     /* Ok, it's a valid xtra field entry */
881     for (j = 0; j < lc; j++) {
882     if (!egg_strcasecmp(list[j], xk->key))
883     dprintf(idx, " %s: %s\n", xk->key, xk->data);
884     }
885     }
886     Tcl_Free((char *) list);
887     }
888    
889     static int xtra_gotshare(struct userrec *u, struct user_entry *e,
890     char *buf, int idx)
891     {
892     char *arg;
893     struct xtra_key *xk;
894     int l;
895    
896     arg = newsplit(&buf);
897     if (!arg[0])
898     return 1;
899    
900     xk = user_malloc(sizeof(struct xtra_key));
901     egg_bzero(xk, sizeof(struct xtra_key));
902     l = strlen(arg);
903     if (l > 500)
904     l = 500;
905     xk->key = user_malloc(l + 1);
906     strncpyz(xk->key, arg, l + 1);
907    
908     if (buf[0]) {
909     int k = strlen(buf);
910    
911     if (k > 500 - l)
912     k = 500 - l;
913     xk->data = user_malloc(k + 1);
914     strncpyz(xk->data, buf, k + 1);
915     }
916     xtra_set(u, e, xk);
917     return 1;
918     }
919    
920     static int xtra_dupuser(struct userrec *new, struct userrec *old,
921     struct user_entry *e)
922     {
923     struct xtra_key *x1, *x2;
924    
925     for (x1 = e->u.extra; x1; x1 = x1->next) {
926     x2 = user_malloc(sizeof(struct xtra_key));
927    
928     x2->key = user_malloc(strlen(x1->key) + 1);
929     strcpy(x2->key, x1->key);
930     x2->data = user_malloc(strlen(x1->data) + 1);
931     strcpy(x2->data, x1->data);
932     set_user(&USERENTRY_XTRA, new, x2);
933     }
934     return 1;
935     }
936    
937     static int xtra_write_userfile(FILE *f, struct userrec *u,
938     struct user_entry *e)
939     {
940     struct xtra_key *x;
941    
942     for (x = e->u.extra; x; x = x->next)
943     if (fprintf(f, "--XTRA %s %s\n", x->key, x->data) == EOF)
944     return 0;
945     return 1;
946     }
947    
948     int xtra_kill(struct user_entry *e)
949     {
950     struct xtra_key *x, *y;
951    
952     for (x = e->u.extra; x; x = y) {
953     y = x->next;
954     nfree(x->key);
955     nfree(x->data);
956     nfree(x);
957     }
958     nfree(e);
959     return 1;
960     }
961    
962     static int xtra_tcl_get(Tcl_Interp * irp, struct userrec *u,
963     struct user_entry *e, int argc, char **argv)
964     {
965     struct xtra_key *x;
966    
967     BADARGS(3, 4, " handle XTRA ?key?");
968    
969     if (argc == 4) {
970     for (x = e->u.extra; x; x = x->next)
971     if (!egg_strcasecmp(argv[3], x->key)) {
972     Tcl_AppendResult(irp, x->data, NULL);
973     return TCL_OK;
974     }
975     return TCL_OK;
976     }
977     for (x = e->u.extra; x; x = x->next) {
978     char *p;
979     EGG_CONST char *list[2];
980    
981     list[0] = x->key;
982     list[1] = x->data;
983     p = Tcl_Merge(2, list);
984     Tcl_AppendElement(irp, p);
985     Tcl_Free((char *) p);
986     }
987     return TCL_OK;
988     }
989    
990     static int xtra_expmem(struct user_entry *e)
991     {
992     struct xtra_key *x;
993     int tot = 0;
994    
995     for (x = e->u.extra; x; x = x->next) {
996     tot += sizeof(struct xtra_key);
997    
998     tot += strlen(x->key) + 1;
999     tot += strlen(x->data) + 1;
1000     }
1001     return tot;
1002     }
1003    
1004     struct user_entry_type USERENTRY_XTRA = {
1005     0,
1006     xtra_gotshare,
1007     xtra_dupuser,
1008     xtra_unpack,
1009     xtra_pack,
1010     xtra_write_userfile,
1011     xtra_kill,
1012     def_get,
1013     xtra_set,
1014     xtra_tcl_get,
1015     xtra_tcl_set,
1016     xtra_expmem,
1017     xtra_display,
1018     "XTRA"
1019     };
1020    
1021     static int hosts_dupuser(struct userrec *new, struct userrec *old,
1022     struct user_entry *e)
1023     {
1024     struct list_type *h;
1025    
1026     for (h = e->u.extra; h; h = h->next)
1027     set_user(&USERENTRY_HOSTS, new, h->extra);
1028     return 1;
1029     }
1030    
1031     static int hosts_null(struct userrec *u, struct user_entry *e)
1032     {
1033     return 1;
1034     }
1035    
1036     static int hosts_write_userfile(FILE *f, struct userrec *u,
1037     struct user_entry *e)
1038     {
1039     struct list_type *h;
1040    
1041     for (h = e->u.extra; h; h = h->next)
1042     if (fprintf(f, "--HOSTS %s\n", h->extra) == EOF)
1043     return 0;
1044     return 1;
1045     }
1046    
1047     static int hosts_kill(struct user_entry *e)
1048     {
1049     list_type_kill(e->u.list);
1050     nfree(e);
1051     return 1;
1052     }
1053    
1054     static int hosts_expmem(struct user_entry *e)
1055     {
1056     return list_type_expmem(e->u.list);
1057     }
1058    
1059     static void hosts_display(int idx, struct user_entry *e)
1060     {
1061     char s[1024];
1062     struct list_type *q;
1063    
1064     s[0] = 0;
1065     strcpy(s, " HOSTS: ");
1066     for (q = e->u.list; q; q = q->next) {
1067     if (s[0] && !s[9])
1068     strcat(s, q->extra);
1069     else if (!s[0])
1070     sprintf(s, " %s", q->extra);
1071     else {
1072     if (strlen(s) + strlen(q->extra) + 2 > 65) {
1073     dprintf(idx, "%s\n", s);
1074     sprintf(s, " %s", q->extra);
1075     } else {
1076     strcat(s, ", ");
1077     strcat(s, q->extra);
1078     }
1079     }
1080     }
1081     if (s[0])
1082     dprintf(idx, "%s\n", s);
1083     }
1084    
1085     static int hosts_set(struct userrec *u, struct user_entry *e, void *buf)
1086     {
1087     if (!buf || !egg_strcasecmp(buf, "none")) {
1088     /* When the bot crashes, it's in this part, not in the 'else' part */
1089     list_type_kill(e->u.list);
1090     e->u.list = NULL;
1091     } else {
1092     char *host = buf, *p = strchr(host, ',');
1093     struct list_type **t;
1094    
1095     /* Can't have ,'s in hostmasks */
1096     while (p) {
1097     *p = '?';
1098     p = strchr(host, ',');
1099     }
1100     /* fred1: check for redundant hostmasks with
1101     * controversial "superpenis" algorithm ;) */
1102     /* I'm surprised Raistlin hasn't gotten involved in this controversy */
1103     t = &(e->u.list);
1104     while (*t) {
1105     if (cmp_usermasks(host, (*t)->extra)) {
1106     struct list_type *u;
1107    
1108     u = *t;
1109     *t = (*t)->next;
1110     if (u->extra)
1111     nfree(u->extra);
1112     nfree(u);
1113     } else
1114     t = &((*t)->next);
1115     }
1116     *t = user_malloc(sizeof(struct list_type));
1117    
1118     (*t)->next = NULL;
1119     (*t)->extra = user_malloc(strlen(host) + 1);
1120     strcpy((*t)->extra, host);
1121     }
1122     return 1;
1123     }
1124    
1125     static int hosts_tcl_get(Tcl_Interp * irp, struct userrec *u,
1126     struct user_entry *e, int argc, char **argv)
1127     {
1128     struct list_type *x;
1129    
1130     BADARGS(3, 3, " handle HOSTS");
1131    
1132     for (x = e->u.list; x; x = x->next)
1133     Tcl_AppendElement(irp, x->extra);
1134     return TCL_OK;
1135     }
1136    
1137     static int hosts_tcl_set(Tcl_Interp * irp, struct userrec *u,
1138     struct user_entry *e, int argc, char **argv)
1139     {
1140     BADARGS(3, 4, " handle HOSTS ?host?");
1141    
1142     if (argc == 4)
1143     addhost_by_handle(u->handle, argv[3]);
1144     else
1145     addhost_by_handle(u->handle, "none"); /* drummer */
1146     return TCL_OK;
1147     }
1148    
1149     static int hosts_gotshare(struct userrec *u, struct user_entry *e,
1150     char *buf, int idx)
1151     {
1152     /* doh, try to be too clever and it bites your butt */
1153     return 0;
1154     }
1155    
1156     struct user_entry_type USERENTRY_HOSTS = {
1157     0,
1158     hosts_gotshare,
1159     hosts_dupuser,
1160     hosts_null,
1161     hosts_null,
1162     hosts_write_userfile,
1163     hosts_kill,
1164     def_get,
1165     hosts_set,
1166     hosts_tcl_get,
1167     hosts_tcl_set,
1168     hosts_expmem,
1169     hosts_display,
1170     "HOSTS"
1171     };
1172    
1173 pseudo 1.3 #ifdef TLS
1174     int fprint_unpack(struct userrec *u, struct user_entry *e)
1175     {
1176     char *tmp;
1177    
1178     tmp = ssl_fpconv(e->u.list->extra, NULL);
1179     nfree(e->u.list->extra);
1180     e->u.list->extra = NULL;
1181     list_type_kill(e->u.list);
1182     e->u.string = tmp;
1183     return 1;
1184     }
1185    
1186     int fprint_set(struct userrec *u, struct user_entry *e, void *buf)
1187     {
1188     char *fp = buf;
1189    
1190     if (!fp || !fp[0] || (fp[0] == '-')) {
1191     if (e->u.string) {
1192     nfree(e->u.string);
1193     e->u.string = NULL;
1194     }
1195     } else {
1196     fp = ssl_fpconv(buf, e->u.string);
1197     if (fp)
1198     e->u.string = fp;
1199     else
1200     return 0;
1201     }
1202     if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
1203     shareout(NULL, "c FPRINT %s %s\n", u->handle, e->u.string ? e->u.string : "");
1204     return 1;
1205     }
1206    
1207     static int fprint_tcl_set(Tcl_Interp * irp, struct userrec *u,
1208     struct user_entry *e, int argc, char **argv)
1209     {
1210     BADARGS(3, 4, " handle FPRINT ?new-fingerprint?");
1211    
1212     fprint_set(u, e, argc == 3 ? NULL : argv[3]);
1213     return TCL_OK;
1214     }
1215    
1216     struct user_entry_type USERENTRY_FPRINT = {
1217     0,
1218     def_gotshare,
1219     0,
1220     fprint_unpack,
1221     def_pack,
1222     def_write_userfile,
1223     def_kill,
1224     def_get,
1225     fprint_set,
1226     def_tcl_get,
1227     fprint_tcl_set,
1228     def_expmem,
1229     0,
1230     "FPRINT"
1231     };
1232     #endif /* TLS */
1233    
1234 simple 1.1 int egg_list_append(struct list_type **h, struct list_type *i)
1235     {
1236     for (; *h; h = &((*h)->next));
1237     *h = i;
1238     return 1;
1239     }
1240    
1241     int egg_list_delete(struct list_type **h, struct list_type *i)
1242     {
1243     for (; *h; h = &((*h)->next))
1244     if (*h == i) {
1245     *h = i->next;
1246     return 1;
1247     }
1248     return 0;
1249     }
1250    
1251     int egg_list_contains(struct list_type *h, struct list_type *i)
1252     {
1253     for (; h; h = h->next)
1254     if (h == i) {
1255     return 1;
1256     }
1257     return 0;
1258     }
1259    
1260     int add_entry_type(struct user_entry_type *type)
1261     {
1262     struct userrec *u;
1263    
1264     list_insert(&entry_type_list, type);
1265     for (u = userlist; u; u = u->next) {
1266     struct user_entry *e = find_user_entry(type, u);
1267    
1268     if (e && e->name) {
1269     e->type = type;
1270 pseudo 1.3
1271 simple 1.1 e->type->unpack(u, e);
1272     nfree(e->name);
1273     e->name = NULL;
1274     }
1275     }
1276     return 1;
1277     }
1278    
1279     int del_entry_type(struct user_entry_type *type)
1280     {
1281     struct userrec *u;
1282    
1283     for (u = userlist; u; u = u->next) {
1284     struct user_entry *e = find_user_entry(type, u);
1285    
1286     if (e && !e->name) {
1287     e->type->pack(u, e);
1288     e->name = user_malloc(strlen(e->type->name) + 1);
1289     strcpy(e->name, e->type->name);
1290     e->type = NULL;
1291     }
1292     }
1293     return egg_list_delete((struct list_type **) &entry_type_list,
1294     (struct list_type *) type);
1295     }
1296    
1297     struct user_entry_type *find_entry_type(char *name)
1298     {
1299     struct user_entry_type *p;
1300    
1301     for (p = entry_type_list; p; p = p->next) {
1302     if (!egg_strcasecmp(name, p->name))
1303     return p;
1304     }
1305     return NULL;
1306     }
1307    
1308     struct user_entry *find_user_entry(struct user_entry_type *et,
1309     struct userrec *u)
1310     {
1311     struct user_entry **e, *t;
1312    
1313     for (e = &(u->entries); *e; e = &((*e)->next)) {
1314     if (((*e)->type == et) ||
1315     ((*e)->name && !egg_strcasecmp((*e)->name, et->name))) {
1316     t = *e;
1317     *e = t->next;
1318     t->next = u->entries;
1319     u->entries = t;
1320     return t;
1321     }
1322     }
1323     return NULL;
1324     }
1325    
1326     void *get_user(struct user_entry_type *et, struct userrec *u)
1327     {
1328     struct user_entry *e;
1329    
1330     if (u && (e = find_user_entry(et, u)))
1331     return et->get(u, e);
1332     return 0;
1333     }
1334    
1335     int set_user(struct user_entry_type *et, struct userrec *u, void *d)
1336     {
1337     struct user_entry *e;
1338     int r;
1339    
1340     if (!u || !et)
1341     return 0;
1342    
1343     if (!(e = find_user_entry(et, u))) {
1344     e = user_malloc(sizeof(struct user_entry));
1345    
1346     e->type = et;
1347     e->name = NULL;
1348     e->u.list = NULL;
1349     list_insert((&(u->entries)), e);
1350     }
1351     r = et->set(u, e, d);
1352     if (!e->u.list) {
1353     egg_list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
1354     nfree(e);
1355     }
1356     return r;
1357     }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23