/[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.8 - (show annotations) (download) (as text)
Sat Dec 11 18:58:04 1999 UTC (19 years, 7 months ago) by fabian
Branch: MAIN
Changes since 1.7: +69 -71 lines
File MIME type: text/x-chdr
tothwolf's remove-context-bloat patch

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23