/[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.4 - (show annotations) (download) (as text)
Thu Oct 21 19:23:01 1999 UTC (19 years, 9 months ago) by fabian
Branch: MAIN
Changes since 1.3: +34 -21 lines
File MIME type: text/x-chdr
resync with 1.3 tree, 939863113-940380771

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23