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

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

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


Revision 1.4 - (show annotations) (download) (as text)
Mon Nov 1 22:38:34 2010 UTC (8 years, 8 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 /*
2 * userent.c -- handles:
3 * user-entry handling, new style more versatile.
4 *
5 * $Id: userent.c,v 1.3 2010/10/19 12:13:33 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
30 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 #ifdef TLS
53 add_entry_type(&USERENTRY_FPRINT);
54 #endif
55 }
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 #ifdef TLS
481 if (*q == '+')
482 bi->ssl |= TLS_BOT;
483 #endif
484 bi->telnet_port = atoi(q);
485 if ((q = strchr(q, '/')))
486 #ifdef TLS
487 {
488 if (q[1] == '+')
489 bi->ssl |= TLS_RELAY;
490 bi->relay_port = atoi(q + 1);
491 }
492 #else
493 bi->relay_port = atoi(q + 1);
494 #endif
495 }
496 #ifdef IPV6
497 for (p = bi->address; *p; p++)
498 if (*p == ';')
499 *p = ':';
500 #endif
501 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 char work[1024], *p, *q = work;
513 struct bot_addr *bi;
514 int l;
515
516 bi = (struct bot_addr *) e->u.extra;
517 for (p = bi->address; *p; p++)
518 if (*p == ':')
519 *q++ = ';';
520 else
521 *q++ = *p;
522 #ifdef TLS
523 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 #endif
529 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 int ret = 1;
550 char *p, *q, *addr;
551 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
552
553 p = bi->address;
554 addr = user_malloc(strlen(bi->address) + 1);
555 for (q = addr; *p; p++)
556 if (*p == ':')
557 *q++ = ';';
558 else
559 *q++ = *p;
560 *q = 0;
561 #ifdef TLS
562 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 if (fprintf(f, "--%s %s:%u/%u\n", e->type->name, addr,
567 bi->telnet_port, bi->relay_port) == EOF)
568 #endif
569 ret = 0;
570 nfree(addr);
571 return ret;
572 }
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 #ifdef TLS
589 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 shareout(NULL, "c BOTADDR %s %s %d %d\n", u->handle,
594 bi->address, bi->telnet_port, bi->relay_port);
595 #endif
596 }
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 #ifdef TLS
607 if (bi->ssl & TLS_BOT)
608 sprintf(number, " +%d", bi->telnet_port);
609 else
610 #endif
611 sprintf(number, " %d", bi->telnet_port);
612 Tcl_AppendResult(interp, bi->address, number, NULL);
613 #ifdef TLS
614 if (bi->ssl & TLS_RELAY)
615 sprintf(number, " +%d", bi->relay_port);
616 else
617 #endif
618 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 #ifdef TLS
641 {
642 if (*argv[4] == '+')
643 bi->ssl |= TLS_BOT;
644 bi->telnet_port = atoi(argv[4]);
645 }
646 #else
647 bi->telnet_port = atoi(argv[4]);
648 #endif
649 if (argc > 5)
650 #ifdef TLS
651 {
652 if (*argv[5] == '+')
653 bi->ssl |= TLS_RELAY;
654 bi->relay_port = atoi(argv[5]);
655 }
656 #else
657 bi->relay_port = atoi(argv[5]);
658 #endif
659 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 #ifdef TLS
681 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 #endif
686 }
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 #ifdef TLS
700 if (*arg == '+')
701 bi->ssl |= TLS_BOT;
702 if (*buf == '+')
703 bi->ssl |= TLS_RELAY;
704 #endif
705 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 #ifdef TLS
728 bi2->ssl = bi->ssl;
729 #endif
730 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 #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 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
1275 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