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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23