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

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

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


Revision 1.2 - (show annotations) (download) (as text)
Sat Oct 9 15:46:35 1999 UTC (19 years, 10 months ago) by fabian
Branch: MAIN
Changes since 1.1: +4 -175 lines
File MIME type: text/x-chdr
all changes to the 1.3 tree merged with 1.4

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23