/[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.5 - (show 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 /*
2 * userent.c -- handles:
3 * user-entry handling, new style more versatile.
4 *
5 * $Id: userent.c,v 1.4 2010/11/01 22:38:34 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 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 #ifdef TLS
477 if (*q == '+')
478 bi->ssl |= TLS_BOT;
479 #endif
480 bi->telnet_port = atoi(q);
481 if ((q = strchr(q, '/')))
482 #ifdef TLS
483 {
484 if (q[1] == '+')
485 bi->ssl |= TLS_RELAY;
486 bi->relay_port = atoi(q + 1);
487 }
488 #else
489 bi->relay_port = atoi(q + 1);
490 #endif
491 }
492 #ifdef IPV6
493 for (p = bi->address; *p; p++)
494 if (*p == ';')
495 *p = ':';
496 #endif
497 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 char work[1024], *p, *q = work;
509 struct bot_addr *bi;
510 int l;
511
512 bi = (struct bot_addr *) e->u.extra;
513 for (p = bi->address; *p; p++)
514 if (*p == ':')
515 *q++ = ';';
516 else
517 *q++ = *p;
518 #ifdef TLS
519 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 #endif
525 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 int ret = 1;
546 char *p, *q, *addr;
547 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
548
549 p = bi->address;
550 addr = user_malloc(strlen(bi->address) + 1);
551 for (q = addr; *p; p++)
552 if (*p == ':')
553 *q++ = ';';
554 else
555 *q++ = *p;
556 *q = 0;
557 #ifdef TLS
558 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 if (fprintf(f, "--%s %s:%u/%u\n", e->type->name, addr,
563 bi->telnet_port, bi->relay_port) == EOF)
564 #endif
565 ret = 0;
566 nfree(addr);
567 return ret;
568 }
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 #ifdef TLS
585 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 shareout(NULL, "c BOTADDR %s %s %d %d\n", u->handle,
590 bi->address, bi->telnet_port, bi->relay_port);
591 #endif
592 }
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 #ifdef TLS
603 if (bi->ssl & TLS_BOT)
604 sprintf(number, " +%d", bi->telnet_port);
605 else
606 #endif
607 sprintf(number, " %d", bi->telnet_port);
608 Tcl_AppendResult(interp, bi->address, number, NULL);
609 #ifdef TLS
610 if (bi->ssl & TLS_RELAY)
611 sprintf(number, " +%d", bi->relay_port);
612 else
613 #endif
614 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 #ifdef TLS
637 {
638 if (*argv[4] == '+')
639 bi->ssl |= TLS_BOT;
640 bi->telnet_port = atoi(argv[4]);
641 }
642 #else
643 bi->telnet_port = atoi(argv[4]);
644 #endif
645 if (argc > 5)
646 #ifdef TLS
647 {
648 if (*argv[5] == '+')
649 bi->ssl |= TLS_RELAY;
650 bi->relay_port = atoi(argv[5]);
651 }
652 #else
653 bi->relay_port = atoi(argv[5]);
654 #endif
655 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 #ifdef TLS
677 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 #endif
682 }
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 #ifdef TLS
696 if (*arg == '+')
697 bi->ssl |= TLS_BOT;
698 if (*buf == '+')
699 bi->ssl |= TLS_RELAY;
700 #endif
701 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 #ifdef TLS
724 bi2->ssl = bi->ssl;
725 #endif
726 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 #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 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
1271 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