/[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.9 - (show annotations) (download) (as text)
Fri Dec 17 18:40:22 1999 UTC (19 years, 7 months ago) by fabian
Branch: MAIN
Changes since 1.8: +26 -27 lines
File MIME type: text/x-chdr
tothwolf's assert-nulls 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 Context;
66 Assert(e);
67 Assert(e->name);
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);
80 Assert(!e->name);
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 Context;
119 Assert(string != e->u.string);
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);
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 Context;
298 Assert(e);
299 Assert(e->name);
300 par = e->u.list->extra;
301 Assert(par);
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);
321 Assert(e->u.extra);
322 Assert(!e->name);
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);
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 Context;
477 Assert(e);
478 Assert(e->name);
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);
509 Assert(!e->name);
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);
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);
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);
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);
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 Context;
768 Assert(e);
769 Assert(e->name);
770 head = curr = e->u.list;
771 e->u.extra = NULL;
772 while (curr) {
773 t = user_malloc(sizeof(struct xtra_key));
774
775 data = curr->extra;
776 key = newsplit(&data);
777 if (data[0]) {
778 t->key = user_malloc(strlen(key) + 1);
779 strcpy(t->key, key);
780 t->data = user_malloc(strlen(data) + 1);
781 strcpy(t->data, data);
782 list_insert((&e->u.extra), t);
783 }
784 curr = curr->next;
785 }
786 list_type_kill(head);
787 return 1;
788 }
789
790 static int xtra_pack(struct userrec *u, struct user_entry *e)
791 {
792 struct list_type *t;
793 struct xtra_key *curr, *next;
794
795 Context;
796 Assert(e);
797 Assert(!e->name);
798 curr = e->u.extra;
799 e->u.list = NULL;
800 while (curr) {
801 t = user_malloc(sizeof(struct list_type));
802 t->extra = user_malloc(strlen(curr->key) + strlen(curr->data) + 4);
803 sprintf(t->extra, "%s %s", curr->key, curr->data);
804 list_insert((&e->u.list), t);
805 next = curr->next;
806 nfree(curr->key);
807 nfree(curr->data);
808 nfree(curr);
809 curr = next;
810 }
811 return 1;
812 }
813
814 static void xtra_display(int idx, struct user_entry *e)
815 {
816 int code, lc, j;
817 struct xtra_key *xk;
818 char **list;
819
820 Context;
821 code = Tcl_SplitList(interp, whois_fields, &lc, &list);
822 if (code == TCL_ERROR)
823 return;
824 /* scan thru xtra field, searching for matches */
825 Context;
826 for (xk = e->u.extra; xk; xk = xk->next) {
827 /* ok, it's a valid xtra field entry */
828 Context;
829 for (j = 0; j < lc; j++) {
830 if (strcasecmp(list[j], xk->key) == 0)
831 dprintf(idx, " %s: %s\n", xk->key, xk->data);
832 }
833 }
834 Tcl_Free((char *) list);
835 Context;
836 }
837
838 static int xtra_gotshare(struct userrec *u, struct user_entry *e,
839 char *buf, int idx)
840 {
841 char *arg;
842 struct xtra_key *xk;
843 int l;
844
845 arg = newsplit (&buf);
846 if (!arg[0])
847 return 1;
848
849 xk = user_malloc (sizeof(struct xtra_key));
850 bzero (xk, sizeof(struct xtra_key));
851 l = strlen(arg);
852 if (l > 500)
853 l = 500;
854 xk->key = user_malloc(l + 1);
855 strncpy(xk->key, arg, l);
856 xk->key[l] = 0;
857
858 if (buf[0]) {
859 int k = strlen(buf);
860
861 if (k > 500 - l)
862 k = 500 - l;
863 xk->data = user_malloc(k + 1);
864 strncpy(xk->data, buf, k);
865 xk->data[k] = 0;
866 }
867 xtra_set(u, e, xk);
868 return 1;
869 }
870
871 static int xtra_dupuser(struct userrec *new, struct userrec *old,
872 struct user_entry *e)
873 {
874 struct xtra_key *x1, *x2;
875
876 for (x1 = e->u.extra; x1; x1 = x1->next) {
877 x2 = user_malloc(sizeof(struct xtra_key));
878
879 x2->key = user_malloc(strlen(x1->key) + 1);
880 strcpy(x2->key, x1->key);
881 x2->data = user_malloc(strlen(x1->data) + 1);
882 strcpy(x2->data, x1->data);
883 set_user(&USERENTRY_XTRA, new, x2);
884 }
885 return 1;
886 }
887
888 static int xtra_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
889 {
890 struct xtra_key *x;
891
892 for (x = e->u.extra; x; x = x->next)
893 if (fprintf(f, "--XTRA %s %s\n", x->key, x->data) == EOF)
894 return 0;
895 return 1;
896 }
897
898 int xtra_kill(struct user_entry *e)
899 {
900 struct xtra_key *x, *y;
901
902 Context;
903 for (x = e->u.extra; x; x = y) {
904 y = x->next;
905 nfree(x->key);
906 nfree(x->data);
907 nfree(x);
908 }
909 nfree(e);
910 Context;
911 return 1;
912 }
913
914 static int xtra_tcl_get(Tcl_Interp * irp, struct userrec *u,
915 struct user_entry *e, int argc, char **argv)
916 {
917 struct xtra_key *x;
918
919 BADARGS(3, 4, " handle XTRA ?key?");
920 if (argc == 4) {
921 for (x = e->u.extra; x; x = x->next)
922 if (!strcasecmp(argv[3], x->key)) {
923 Tcl_AppendResult(irp, x->data, NULL);
924 return TCL_OK;
925 }
926 return TCL_OK;
927 }
928 for (x = e->u.extra; x; x = x->next) {
929 char *p, *list[2];
930
931 list[0] = x->key;
932 list[1] = x->data;
933 p = Tcl_Merge(2, list);
934 Tcl_AppendElement(irp, p);
935 Tcl_Free((char *) p);
936 }
937 return TCL_OK;
938 }
939
940 static int xtra_expmem(struct user_entry *e)
941 {
942 struct xtra_key *x;
943 int tot = 0;
944
945 for (x = e->u.extra; x; x = x->next) {
946 tot += sizeof(struct xtra_key);
947
948 tot += strlen(x->key) + 1;
949 tot += strlen(x->data) + 1;
950 }
951 return tot;
952 }
953
954 struct user_entry_type USERENTRY_XTRA =
955 {
956 0,
957 xtra_gotshare,
958 xtra_dupuser,
959 xtra_unpack,
960 xtra_pack,
961 xtra_write_userfile,
962 xtra_kill,
963 def_get,
964 xtra_set,
965 xtra_tcl_get,
966 xtra_tcl_set,
967 xtra_expmem,
968 xtra_display,
969 "XTRA"
970 };
971
972 static int hosts_dupuser(struct userrec *new, struct userrec *old,
973 struct user_entry *e)
974 {
975 struct list_type *h;
976
977 for (h = e->u.extra; h; h = h->next)
978 set_user(&USERENTRY_HOSTS, new, h->extra);
979 return 1;
980 }
981
982 static int hosts_null(struct userrec *u, struct user_entry *e)
983 {
984 return 1;
985 }
986
987 static int hosts_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
988 {
989 struct list_type *h;
990
991 for (h = e->u.extra; h; h = h->next)
992 if (fprintf(f, "--HOSTS %s\n", h->extra) == EOF)
993 return 0;
994 return 1;
995 }
996
997 static int hosts_kill(struct user_entry *e)
998 {
999 list_type_kill(e->u.list);
1000 nfree(e);
1001 return 1;
1002 }
1003
1004 static int hosts_expmem(struct user_entry *e)
1005 {
1006 return list_type_expmem(e->u.list);
1007 }
1008
1009 static void hosts_display(int idx, struct user_entry *e)
1010 {
1011 char s[1024];
1012 struct list_type *q;
1013
1014 s[0] = 0;
1015 strcpy(s, " HOSTS: ");
1016 for (q = e->u.list; q; q = q->next) {
1017 if (s[0] && !s[9])
1018 strcat(s, q->extra);
1019 else if (!s[0])
1020 simple_sprintf(s, " %s", q->extra);
1021 else {
1022 if (strlen(s) + strlen(q->extra) + 2 > 65) {
1023 dprintf(idx, "%s\n", s);
1024 simple_sprintf(s, " %s", q->extra);
1025 } else {
1026 strcat(s, ", ");
1027 strcat(s, q->extra);
1028 }
1029 }
1030 }
1031 if (s[0])
1032 dprintf(idx, "%s\n", s);
1033 }
1034
1035 static int hosts_set(struct userrec *u, struct user_entry *e, void *buf)
1036 {
1037 Context;
1038 if (!buf || !strcasecmp(buf, "none")) {
1039 ContextNote("SEGV with sharing bug track");
1040 /* when the bot crashes, it's in this part, not in the 'else' part */
1041 ContextNote(e ? "e is valid" : "e is NULL!");
1042 Assert(e); /* e cannot be null -- rtc */
1043 ContextNote((e->u.list) ? "(sharebug) e->u.list is valid" : "(sharebug) e->u.list is NULL!");
1044 list_type_kill(e->u.list);
1045 ContextNote("(sharebug[c1]) occurred in hosts_set - added 99/03/26");
1046 e->u.list = NULL;
1047 ContextNote("(sharebug[c2]) occurred in hosts_set - added 99/03/26");
1048 } else {
1049 char *host = buf, *p = strchr(host, ',');
1050 struct list_type **t;
1051
1052 ContextNote("SEGV with sharing bug track");
1053 /* can't have ,'s in hostmasks */
1054 while (p) {
1055 *p = '?';
1056 p = strchr(host, ',');
1057 }
1058 /* fred1: check for redundant hostmasks with
1059 * controversial "superpenis" algorithm ;) */
1060 /* I'm surprised Raistlin hasn't gotten involved in this controversy */
1061 t = &(e->u.list);
1062 while (*t) {
1063 if (wild_match(host, (*t)->extra)) {
1064 struct list_type *u;
1065
1066 u = *t;
1067 *t = (*t)->next;
1068 if (u->extra)
1069 nfree(u->extra);
1070 nfree(u);
1071 } else
1072 t = &((*t)->next);
1073 }
1074 *t = user_malloc(sizeof(struct list_type));
1075
1076 (*t)->next = NULL;
1077 (*t)->extra = user_malloc(strlen(host) + 1);
1078 strcpy((*t)->extra, host);
1079 }
1080 ContextNote("please visit http://www.eggheads.org/bugs.html now.");
1081 return 1;
1082 }
1083
1084 static int hosts_tcl_get(Tcl_Interp * irp, struct userrec *u,
1085 struct user_entry *e, int argc, char **argv)
1086 {
1087 struct list_type *x;
1088
1089 BADARGS(3, 3, " handle HOSTS");
1090 for (x = e->u.list; x; x = x->next)
1091 Tcl_AppendElement(irp, x->extra);
1092 return TCL_OK;
1093 }
1094
1095 static int hosts_tcl_set(Tcl_Interp * irp, struct userrec *u,
1096 struct user_entry *e, int argc, char **argv)
1097 {
1098 BADARGS(3, 4, " handle HOSTS ?host?");
1099 if (argc == 4)
1100 addhost_by_handle(u->handle, argv[3]);
1101 else /* {
1102 while (e->u.list && strcasecmp(e->u.list->extra, "none"))
1103 delhost_by_handle(u->handle, e->u.list->extra);
1104 } */
1105 addhost_by_handle(u->handle, "none"); /* drummer */
1106 return TCL_OK;
1107 }
1108
1109 static int hosts_gotshare(struct userrec *u, struct user_entry *e,
1110 char *buf, int idx)
1111 {
1112 /* doh, try to be too clever and it bites your butt */
1113 return 0;
1114 }
1115
1116 struct user_entry_type USERENTRY_HOSTS =
1117 {
1118 0,
1119 hosts_gotshare,
1120 hosts_dupuser,
1121 hosts_null,
1122 hosts_null,
1123 hosts_write_userfile,
1124 hosts_kill,
1125 def_get,
1126 hosts_set,
1127 hosts_tcl_get,
1128 hosts_tcl_set,
1129 hosts_expmem,
1130 hosts_display,
1131 "HOSTS"
1132 };
1133
1134 int list_append(struct list_type **h, struct list_type *i)
1135 {
1136 for (; *h; h = &((*h)->next));
1137 *h = i;
1138 return 1;
1139 }
1140
1141 int list_delete(struct list_type **h, struct list_type *i)
1142 {
1143 for (; *h; h = &((*h)->next))
1144 if (*h == i) {
1145 *h = i->next;
1146 return 1;
1147 }
1148 return 0;
1149 }
1150
1151 int list_contains(struct list_type *h, struct list_type *i)
1152 {
1153 for (; h; h = h->next)
1154 if (h == i) {
1155 return 1;
1156 }
1157 return 0;
1158 }
1159
1160 int add_entry_type(struct user_entry_type *type)
1161 {
1162 struct userrec *u;
1163
1164 list_insert(&entry_type_list, type);
1165 for (u = userlist; u; u = u->next) {
1166 struct user_entry *e = find_user_entry(type, u);
1167
1168 if (e && e->name) {
1169 e->type = type;
1170 e->type->unpack(u, e);
1171 nfree(e->name);
1172 e->name = NULL;
1173 }
1174 }
1175 return 1;
1176 }
1177
1178 int del_entry_type(struct user_entry_type *type)
1179 {
1180 struct userrec *u;
1181
1182 for (u = userlist; u; u = u->next) {
1183 struct user_entry *e = find_user_entry(type, u);
1184
1185 if (e && !e->name) {
1186 e->type->pack(u, e);
1187 e->name = user_malloc(strlen(e->type->name) + 1);
1188 strcpy(e->name, e->type->name);
1189 e->type = NULL;
1190 }
1191 }
1192 return list_delete((struct list_type **) &entry_type_list,
1193 (struct list_type *) type);
1194 }
1195
1196 struct user_entry_type *find_entry_type(char *name)
1197 {
1198 struct user_entry_type *p;
1199
1200 for (p = entry_type_list; p; p = p->next) {
1201 if (!strcasecmp(name, p->name))
1202 return p;
1203 }
1204 return NULL;
1205 }
1206
1207 struct user_entry *find_user_entry(struct user_entry_type *et,
1208 struct userrec *u)
1209 {
1210 struct user_entry **e, *t;
1211
1212 for (e = &(u->entries); *e; e = &((*e)->next)) {
1213 if (((*e)->type == et) ||
1214 ((*e)->name && !strcasecmp((*e)->name, et->name))) {
1215 t = *e;
1216 *e = t->next;
1217 t->next = u->entries;
1218 u->entries = t;
1219 return t;
1220 }
1221 }
1222 return NULL;
1223 }
1224
1225 void *get_user(struct user_entry_type *et, struct userrec *u)
1226 {
1227 struct user_entry *e;
1228
1229 if (u && (e = find_user_entry(et, u)))
1230 return et->get(u, e);
1231 return 0;
1232 }
1233
1234 int set_user(struct user_entry_type *et, struct userrec *u, void *d)
1235 {
1236 struct user_entry *e;
1237 int r;
1238
1239 if (!u || !et)
1240 return 0;
1241
1242 if (!(e = find_user_entry(et, u))) {
1243 e = user_malloc(sizeof(struct user_entry));
1244
1245 e->type = et;
1246 e->name = NULL;
1247 e->u.list = NULL;
1248 list_insert((&(u->entries)), e);
1249 }
1250 r = et->set(u, e, d);
1251 if (!e->u.list) {
1252 list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
1253 nfree(e);
1254 }
1255 return r;
1256 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23