/[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.5 - (show annotations) (download) (as text)
Tue Oct 26 21:38:37 1999 UTC (20 years, 1 month ago) by fabian
Branch: MAIN
Changes since 1.4: +18 -9 lines
File MIME type: text/x-chdr
resync 940380771-940924890

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(4, 5, " handle LASTON time ?place?");
409
410 if ((argc == 5) && argv[4][0] && strchr(CHANMETA, argv[4][0])) {
411 /* Search for matching channel */
412 for (cr = u->chanrec; cr; cr = cr->next)
413 if (!rfc_casecmp(cr->channel, argv[4])) {
414 cr->laston = atoi(argv[3]);
415 break;
416 }
417 }
418 /* Save globally */
419 li = user_malloc(sizeof(struct laston_info));
420
421 if (argc == 5) {
422 li->lastonplace = user_malloc(strlen(argv[4]) + 1);
423 strcpy(li->lastonplace, argv[4]);
424 } else {
425 li->lastonplace = user_malloc(1);
426 li->lastonplace[0] = 0;
427 }
428 li->laston = atoi(argv[3]);
429 set_user(&USERENTRY_LASTON, u, li);
430 return TCL_OK;
431 }
432
433 static int laston_expmem(struct user_entry *e)
434 {
435 context;
436 return sizeof(struct laston_info) +
437 strlen(((struct laston_info *) (e->u.extra))->lastonplace) + 1;
438 }
439
440 static int laston_dupuser(struct userrec *new, struct userrec *old,
441 struct user_entry *e)
442 {
443 struct laston_info *li = e->u.extra, *li2;
444
445 if (li) {
446 li2 = user_malloc(sizeof(struct laston_info));
447
448 li2->laston = li->laston;
449 li2->lastonplace = user_malloc(strlen(li->lastonplace) + 1);
450 strcpy(li2->lastonplace, li->lastonplace);
451 return set_user(&USERENTRY_LASTON, new, li2);
452 }
453 return 0;
454 }
455
456 struct user_entry_type USERENTRY_LASTON =
457 {
458 0, /* always 0 ;) */
459 0,
460 laston_dupuser,
461 laston_unpack,
462 laston_pack,
463 laston_write_userfile,
464 laston_kill,
465 def_get,
466 laston_set,
467 laston_tcl_get,
468 laston_tcl_set,
469 laston_expmem,
470 0,
471 "LASTON"
472 };
473
474 static int botaddr_unpack(struct userrec *u, struct user_entry *e)
475 {
476 char *p, *q;
477 struct bot_addr *bi = user_malloc(sizeof(struct bot_addr));
478
479 ASSERT (e != NULL);
480 ASSERT (e->name != NULL);
481 context;
482 bzero (bi, sizeof(struct bot_addr));
483
484 if (!(q = strchr ((p = e->u.list->extra), ':'))) {
485 bi->address = user_malloc (strlen (p) + 1);
486 strcpy (bi->address, p);
487 } else {
488 bi->address = user_malloc((q - p) + 1);
489 strncpy(bi->address, p, q - p);
490 bi->address[q - p] = 0;
491 q++;
492 bi->telnet_port = atoi(q);
493 if ((q = strchr(q, '/')))
494 bi->relay_port = atoi(q + 1);
495 }
496 if (!bi->telnet_port)
497 bi->telnet_port = 3333;
498 if (!bi->relay_port)
499 bi->relay_port = bi->telnet_port;
500 list_type_kill(e->u.list);
501 e->u.extra = bi;
502 return 1;
503 }
504
505 static int botaddr_pack(struct userrec *u, struct user_entry *e)
506 {
507 char work[1024];
508 struct bot_addr *bi;
509 int l;
510
511 ASSERT (e != NULL);
512 ASSERT (e->name == NULL);
513 bi = (struct bot_addr *) e->u.extra;
514 l = simple_sprintf(work, "%s:%u/%u", bi->address, bi->telnet_port,
515 bi->relay_port);
516 e->u.list = user_malloc(sizeof(struct list_type));
517 e->u.list->next = NULL;
518 e->u.list->extra = user_malloc(l + 1);
519 strcpy(e->u.list->extra, work);
520 nfree(bi->address);
521 nfree(bi);
522 return 1;
523 }
524
525 static int botaddr_kill(struct user_entry *e)
526 {
527 context;
528 nfree(((struct bot_addr *) (e->u.extra))->address);
529 nfree(e->u.extra);
530 nfree(e);
531 context;
532 return 1;
533 }
534
535 static int botaddr_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
536 {
537 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
538
539 context;
540 if (fprintf(f, "--%s %s:%u/%u\n", e->type->name, bi->address,
541 bi->telnet_port, bi->relay_port) == EOF)
542 return 0;
543 return 1;
544 }
545
546 static int botaddr_set(struct userrec *u, struct user_entry *e, void *buf)
547 {
548 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
549
550 context;
551 if (!bi && !buf)
552 return 1;
553 if (bi != buf) {
554 if (bi) {
555 ASSERT (bi->address != NULL);
556 nfree (bi->address);
557 nfree (bi);
558 }
559 contextnote("(sharebug) occurred in botaddr_set");
560 bi = e->u.extra = buf;
561 }
562 ASSERT (u != NULL);
563 if (bi && !noshare && !(u->flags & USER_UNSHARED)) {
564 shareout(NULL, "c BOTADDR %s %s %d %d\n", u->handle,
565 bi->address, bi->telnet_port, bi->relay_port);
566 }
567 return 1;
568 }
569
570 static int botaddr_tcl_get(Tcl_Interp * interp, struct userrec *u,
571 struct user_entry *e, int argc, char **argv)
572 {
573 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
574 char number[20];
575
576 context;
577 sprintf(number, " %d", bi->telnet_port);
578 Tcl_AppendResult(interp, bi->address, number, NULL);
579 sprintf(number, " %d", bi->relay_port);
580 Tcl_AppendResult(interp, number, NULL);
581 return TCL_OK;
582 }
583
584 static int botaddr_tcl_set(Tcl_Interp * irp, struct userrec *u,
585 struct user_entry *e, int argc, char **argv)
586 {
587 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
588
589 BADARGS(4, 6, " handle type address ?telnetport ?relayport??");
590 if (u->flags & USER_BOT) {
591 /* silently ignore for users */
592 if (!bi) {
593 bi = user_malloc(sizeof(struct bot_addr));
594 bzero (bi, sizeof (struct bot_addr));
595 } else {
596 ASSERT (bi->address != NULL);
597 nfree(bi->address);
598 }
599 bi->address = user_malloc(strlen(argv[3]) + 1);
600 strcpy(bi->address, argv[3]);
601 if (argc > 4)
602 bi->telnet_port = atoi(argv[4]);
603 if (argc > 5)
604 bi->relay_port = atoi(argv[5]);
605 if (!bi->telnet_port)
606 bi->telnet_port = 3333;
607 if (!bi->relay_port)
608 bi->relay_port = bi->telnet_port;
609 botaddr_set(u, e, bi);
610 }
611 return TCL_OK;
612 }
613
614 static int botaddr_expmem(struct user_entry *e)
615 {
616 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
617
618 context;
619 return strlen(bi->address) + 1 + sizeof(struct bot_addr);
620 }
621
622 static void botaddr_display(int idx, struct user_entry *e)
623 {
624 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
625
626 context;
627 dprintf(idx, " ADDRESS: %.70s\n", bi->address);
628 dprintf(idx, " telnet: %d, relay: %d\n", bi->telnet_port, bi->relay_port);
629 }
630
631 static int botaddr_gotshare(struct userrec *u, struct user_entry *e,
632 char *buf, int idx)
633 {
634 struct bot_addr *bi = user_malloc(sizeof(struct bot_addr));
635 char *arg;
636
637 bzero (bi, sizeof(struct bot_addr));
638 arg = newsplit(&buf);
639 bi->address = user_malloc(strlen(arg) + 1);
640 strcpy(bi->address, arg);
641 arg = newsplit(&buf);
642 bi->telnet_port = atoi(arg);
643 bi->relay_port = atoi(buf);
644 if (!bi->telnet_port)
645 bi->telnet_port = 3333;
646 if (!bi->relay_port)
647 bi->relay_port = bi->telnet_port;
648 if (!(dcc[idx].status & STAT_GETTING))
649 putlog(LOG_CMDS, "*", "%s: change botaddr %s", dcc[idx].nick,
650 u->handle);
651 return botaddr_set(u, e, bi);
652 }
653
654 static int botaddr_dupuser(struct userrec *new, struct userrec *old,
655 struct user_entry *e)
656 {
657 if (old->flags & USER_BOT) {
658 struct bot_addr *bi = e->u.extra, *bi2;
659
660 if (bi) {
661 bi2 = user_malloc(sizeof(struct bot_addr));
662
663 bi2->telnet_port = bi->telnet_port;
664 bi2->relay_port = bi->relay_port;
665 bi2->address = user_malloc(strlen(bi->address) + 1);
666 strcpy(bi2->address, bi->address);
667 return set_user(&USERENTRY_BOTADDR, new, bi2);
668 }
669 }
670 return 0;
671 }
672
673 struct user_entry_type USERENTRY_BOTADDR =
674 {
675 0, /* always 0 ;) */
676 botaddr_gotshare,
677 botaddr_dupuser,
678 botaddr_unpack,
679 botaddr_pack,
680 botaddr_write_userfile,
681 botaddr_kill,
682 def_get,
683 botaddr_set,
684 botaddr_tcl_get,
685 botaddr_tcl_set,
686 botaddr_expmem,
687 botaddr_display,
688 "BOTADDR"
689 };
690
691 int xtra_set(struct userrec *u, struct user_entry *e, void *buf)
692 {
693 struct xtra_key *curr, *old = NULL, *new = buf;
694
695 ASSERT (new != NULL);
696 context;
697 for (curr = e->u.extra; curr; curr = curr->next) {
698 if (curr->key && !strcasecmp(curr->key, new->key)) {
699 old = curr;
700 break;
701 }
702 }
703 if (!old && (!new->data || !new->data[0])) {
704 /* delete non-existant entry -- doh ++rtc */
705 nfree(new->key);
706 if (new->data)
707 nfree(new->data);
708 nfree(new);
709 return TCL_OK;
710 }
711
712 /* we will possibly free new below, so let's send the information
713 * to the botnet now */
714 if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
715 shareout(NULL, "c XTRA %s %s %s\n", u->handle, new->key,
716 new->data ? new->data : "");
717 if ((old && old != new) || !new->data || !new->data[0]) {
718 list_delete((struct list_type **) (&e->u.extra),
719 (struct list_type *) old);
720 nfree(old->key);
721 nfree(old->data);
722 nfree(old);
723 }
724 if (old != new) {
725 if (new->data && new->data[0])
726 list_insert((&e->u.extra), new) /* do not add a ';' here */
727 else {
728 if (new->data)
729 nfree(new->data);
730 nfree(new->key);
731 nfree(new);
732 }
733 }
734 return TCL_OK;
735 }
736
737 static int xtra_tcl_set(Tcl_Interp * irp, struct userrec *u,
738 struct user_entry *e, int argc, char **argv)
739 {
740 struct xtra_key *xk;
741 int l;
742
743 BADARGS(4, 5, " handle type key ?value?");
744 xk = user_malloc(sizeof(struct xtra_key));
745 l = strlen(argv[3]);
746 bzero (xk, sizeof (struct xtra_key));
747 if (l > 500)
748 l = 500;
749 xk->key = user_malloc(l + 1);
750 strncpy(xk->key, argv[3], l);
751 xk->key[l] = 0;
752
753 if (argc == 5) {
754 int k = strlen(argv[4]);
755 if (k > 500 - l)
756 k = 500 - l;
757 xk->data = user_malloc(k + 1);
758 strncpy(xk->data, argv[4], k);
759 xk->data[k] = 0;
760 }
761 xtra_set(u, e, xk);
762 return TCL_OK;
763 }
764
765 int xtra_unpack(struct userrec *u, struct user_entry *e)
766 {
767 struct list_type *curr, *head;
768 struct xtra_key *t;
769 char *key, *data;
770
771 ASSERT (e != NULL);
772 ASSERT (e->name != NULL);
773 context;
774
775 head = curr = e->u.list;
776 e->u.extra = NULL;
777 while (curr) {
778 t = user_malloc(sizeof(struct xtra_key));
779
780 data = curr->extra;
781 key = newsplit(&data);
782 if (data[0]) {
783 t->key = user_malloc(strlen(key) + 1);
784 strcpy(t->key, key);
785 t->data = user_malloc(strlen(data) + 1);
786 strcpy(t->data, data);
787 list_insert((&e->u.extra), t);
788 }
789 curr = curr->next;
790 }
791 list_type_kill(head);
792 return 1;
793 }
794
795 static int xtra_pack(struct userrec *u, struct user_entry *e)
796 {
797 struct list_type *t;
798 struct xtra_key *curr, *next;
799
800 ASSERT (e != NULL);
801 ASSERT (e->name == NULL);
802 context;
803 curr = e->u.extra;
804 e->u.list = NULL;
805 while (curr) {
806 t = user_malloc(sizeof(struct list_type));
807 t->extra = user_malloc(strlen(curr->key) + strlen(curr->data) + 4);
808 sprintf(t->extra, "%s %s", curr->key, curr->data);
809 list_insert((&e->u.list), t);
810 next = curr->next;
811 nfree(curr->key);
812 nfree(curr->data);
813 nfree(curr);
814 curr = next;
815 }
816 return 1;
817 }
818
819 static void xtra_display(int idx, struct user_entry *e)
820 {
821 int code, lc, j;
822 struct xtra_key *xk;
823 char **list;
824
825 context;
826 code = Tcl_SplitList(interp, whois_fields, &lc, &list);
827 if (code == TCL_ERROR)
828 return;
829 /* scan thru xtra field, searching for matches */
830 context;
831 for (xk = e->u.extra; xk; xk = xk->next) {
832 /* ok, it's a valid xtra field entry */
833 context;
834 for (j = 0; j < lc; j++) {
835 if (strcasecmp(list[j], xk->key) == 0)
836 dprintf(idx, " %s: %s\n", xk->key, xk->data);
837 }
838 }
839 n_free(list, "", 0);
840 context;
841 }
842
843 static int xtra_gotshare(struct userrec *u, struct user_entry *e,
844 char *buf, int idx)
845 {
846 char *arg;
847 struct xtra_key *xk;
848 int l;
849
850 arg = newsplit (&buf);
851 if (!arg[0])
852 return 1;
853
854 xk = user_malloc (sizeof(struct xtra_key));
855 bzero (xk, sizeof(struct xtra_key));
856 l = strlen(arg);
857 if (l > 500)
858 l = 500;
859 xk->key = user_malloc(l + 1);
860 strncpy(xk->key, arg, l);
861 xk->key[l] = 0;
862
863 if (buf[0]) {
864 int k = strlen(buf);
865
866 if (k > 500 - l)
867 k = 500 - l;
868 xk->data = user_malloc(k + 1);
869 strncpy(xk->data, buf, k);
870 xk->data[k] = 0;
871 }
872 xtra_set(u, e, xk);
873 return 1;
874 }
875
876 static int xtra_dupuser(struct userrec *new, struct userrec *old,
877 struct user_entry *e)
878 {
879 struct xtra_key *x1, *x2;
880
881 for (x1 = e->u.extra; x1; x1 = x1->next) {
882 x2 = user_malloc(sizeof(struct xtra_key));
883
884 x2->key = user_malloc(strlen(x1->key) + 1);
885 strcpy(x2->key, x1->key);
886 x2->data = user_malloc(strlen(x1->data) + 1);
887 strcpy(x2->data, x1->data);
888 set_user(&USERENTRY_XTRA, new, x2);
889 }
890 return 1;
891 }
892
893 static int xtra_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
894 {
895 struct xtra_key *x;
896
897 for (x = e->u.extra; x; x = x->next)
898 if (fprintf(f, "--XTRA %s %s\n", x->key, x->data) == EOF)
899 return 0;
900 return 1;
901 }
902
903 int xtra_kill(struct user_entry *e)
904 {
905 struct xtra_key *x, *y;
906
907 context;
908 for (x = e->u.extra; x; x = y) {
909 y = x->next;
910 nfree(x->key);
911 nfree(x->data);
912 nfree(x);
913 }
914 nfree(e);
915 context;
916 return 1;
917 }
918
919 static int xtra_tcl_get(Tcl_Interp * irp, struct userrec *u,
920 struct user_entry *e, int argc, char **argv)
921 {
922 struct xtra_key *x;
923
924 BADARGS(3, 4, " handle XTRA ?key?");
925 if (argc == 4) {
926 for (x = e->u.extra; x; x = x->next)
927 if (!strcasecmp(argv[3], x->key)) {
928 Tcl_AppendResult(irp, x->data, NULL);
929 return TCL_OK;
930 }
931 return TCL_OK;
932 }
933 for (x = e->u.extra; x; x = x->next) {
934 char *p, *list[2];
935
936 list[0] = x->key;
937 list[1] = x->data;
938 p = Tcl_Merge(2, list);
939 Tcl_AppendElement(irp, p);
940 n_free(p, "", 0);
941 }
942 return TCL_OK;
943 }
944
945 static int xtra_expmem(struct user_entry *e)
946 {
947 struct xtra_key *x;
948 int tot = 0;
949
950 for (x = e->u.extra; x; x = x->next) {
951 tot += sizeof(struct xtra_key);
952
953 tot += strlen(x->key) + 1;
954 tot += strlen(x->data) + 1;
955 }
956 return tot;
957 }
958
959 struct user_entry_type USERENTRY_XTRA =
960 {
961 0,
962 xtra_gotshare,
963 xtra_dupuser,
964 xtra_unpack,
965 xtra_pack,
966 xtra_write_userfile,
967 xtra_kill,
968 def_get,
969 xtra_set,
970 xtra_tcl_get,
971 xtra_tcl_set,
972 xtra_expmem,
973 xtra_display,
974 "XTRA"
975 };
976
977 static int hosts_dupuser(struct userrec *new, struct userrec *old,
978 struct user_entry *e)
979 {
980 struct list_type *h;
981
982 for (h = e->u.extra; h; h = h->next)
983 set_user(&USERENTRY_HOSTS, new, h->extra);
984 return 1;
985 }
986
987 static int hosts_null(struct userrec *u, struct user_entry *e)
988 {
989 return 1;
990 }
991
992 static int hosts_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
993 {
994 struct list_type *h;
995
996 for (h = e->u.extra; h; h = h->next)
997 if (fprintf(f, "--HOSTS %s\n", h->extra) == EOF)
998 return 0;
999 return 1;
1000 }
1001
1002 static int hosts_kill(struct user_entry *e)
1003 {
1004 list_type_kill(e->u.list);
1005 nfree(e);
1006 return 1;
1007 }
1008
1009 static int hosts_expmem(struct user_entry *e)
1010 {
1011 return list_type_expmem(e->u.list);
1012 }
1013
1014 static void hosts_display(int idx, struct user_entry *e)
1015 {
1016 char s[1024];
1017 struct list_type *q;
1018
1019 s[0] = 0;
1020 strcpy(s, " HOSTS: ");
1021 for (q = e->u.list; q; q = q->next) {
1022 if (s[0] && !s[9])
1023 strcat(s, q->extra);
1024 else if (!s[0])
1025 simple_sprintf(s, " %s", q->extra);
1026 else {
1027 if (strlen(s) + strlen(q->extra) + 2 > 65) {
1028 dprintf(idx, "%s\n", s);
1029 simple_sprintf(s, " %s", q->extra);
1030 } else {
1031 strcat(s, ", ");
1032 strcat(s, q->extra);
1033 }
1034 }
1035 }
1036 if (s[0])
1037 dprintf(idx, "%s\n", s);
1038 }
1039
1040 static int hosts_set(struct userrec *u, struct user_entry *e, void *buf)
1041 {
1042 context;
1043 if (!buf || !strcasecmp(buf, "none")) {
1044 contextnote("SEGV with sharing bug track");
1045 /* when the bot crashes, it's in this part, not in the 'else' part */
1046 contextnote(e ? "e is valid" : "e is NULL!");
1047 ASSERT (e != NULL); /* e cannot be null ++rtc */
1048 contextnote((e->u.list) ? "(sharebug) e->u.list is valid" : "(sharebug) e->u.list is NULL!");
1049 list_type_kill(e->u.list);
1050 contextnote("(sharebug[c1]) occurred in hosts_set - added 99/03/26");
1051 e->u.list = NULL;
1052 contextnote("(sharebug[c2]) occurred in hosts_set - added 99/03/26");
1053 } else {
1054 char *host = buf, *p = strchr(host, ',');
1055 struct list_type **t;
1056
1057 contextnote("SEGV with sharing bug track");
1058 /* can't have ,'s in hostmasks */
1059 while (p) {
1060 *p = '?';
1061 p = strchr(host, ',');
1062 }
1063 /* fred1: check for redundant hostmasks with
1064 * controversial "superpenis" algorithm ;) */
1065 /* I'm surprised Raistlin hasn't gotten involved in this controversy */
1066 t = &(e->u.list);
1067 while (*t) {
1068 if (wild_match(host, (*t)->extra)) {
1069 struct list_type *u;
1070
1071 u = *t;
1072 *t = (*t)->next;
1073 if (u->extra)
1074 nfree(u->extra);
1075 nfree(u);
1076 } else
1077 t = &((*t)->next);
1078 }
1079 *t = user_malloc(sizeof(struct list_type));
1080
1081 (*t)->next = NULL;
1082 (*t)->extra = user_malloc(strlen(host) + 1);
1083 strcpy((*t)->extra, host);
1084 }
1085 contextnote("please visit http://www.eggheads.org/bugs.html now.");
1086 return 1;
1087 }
1088
1089 static int hosts_tcl_get(Tcl_Interp * irp, struct userrec *u,
1090 struct user_entry *e, int argc, char **argv)
1091 {
1092 struct list_type *x;
1093
1094 BADARGS(3, 3, " handle HOSTS");
1095 for (x = e->u.list; x; x = x->next)
1096 Tcl_AppendElement(irp, x->extra);
1097 return TCL_OK;
1098 }
1099
1100 static int hosts_tcl_set(Tcl_Interp * irp, struct userrec *u,
1101 struct user_entry *e, int argc, char **argv)
1102 {
1103 BADARGS(3, 4, " handle HOSTS ?host?");
1104 if (argc == 4)
1105 addhost_by_handle(u->handle, argv[3]);
1106 else /* {
1107 while (e->u.list && strcasecmp(e->u.list->extra, "none"))
1108 delhost_by_handle(u->handle, e->u.list->extra);
1109 } */
1110 addhost_by_handle(u->handle, "none"); /* drummer */
1111 return TCL_OK;
1112 }
1113
1114 static int hosts_gotshare(struct userrec *u, struct user_entry *e,
1115 char *buf, int idx)
1116 {
1117 /* doh, try to be too clever and it bites your butt */
1118 return 0;
1119 }
1120
1121 struct user_entry_type USERENTRY_HOSTS =
1122 {
1123 0,
1124 hosts_gotshare,
1125 hosts_dupuser,
1126 hosts_null,
1127 hosts_null,
1128 hosts_write_userfile,
1129 hosts_kill,
1130 def_get,
1131 hosts_set,
1132 hosts_tcl_get,
1133 hosts_tcl_set,
1134 hosts_expmem,
1135 hosts_display,
1136 "HOSTS"
1137 };
1138
1139 int list_append(struct list_type **h, struct list_type *i)
1140 {
1141 for (; *h; h = &((*h)->next));
1142 *h = i;
1143 return 1;
1144 }
1145
1146 int list_delete(struct list_type **h, struct list_type *i)
1147 {
1148 for (; *h; h = &((*h)->next))
1149 if (*h == i) {
1150 *h = i->next;
1151 return 1;
1152 }
1153 return 0;
1154 }
1155
1156 int list_contains(struct list_type *h, struct list_type *i)
1157 {
1158 for (; h; h = h->next)
1159 if (h == i) {
1160 return 1;
1161 }
1162 return 0;
1163 }
1164
1165 int add_entry_type(struct user_entry_type *type)
1166 {
1167 struct userrec *u;
1168
1169 list_insert(&entry_type_list, type);
1170 for (u = userlist; u; u = u->next) {
1171 struct user_entry *e = find_user_entry(type, u);
1172
1173 if (e && e->name) {
1174 e->type = type;
1175 e->type->unpack(u, e);
1176 nfree(e->name);
1177 e->name = NULL;
1178 }
1179 }
1180 return 1;
1181 }
1182
1183 int del_entry_type(struct user_entry_type *type)
1184 {
1185 struct userrec *u;
1186
1187 for (u = userlist; u; u = u->next) {
1188 struct user_entry *e = find_user_entry(type, u);
1189
1190 if (e && !e->name) {
1191 e->type->pack(u, e);
1192 e->name = user_malloc(strlen(e->type->name) + 1);
1193 strcpy(e->name, e->type->name);
1194 e->type = NULL;
1195 }
1196 }
1197 return list_delete((struct list_type **) &entry_type_list,
1198 (struct list_type *) type);
1199 }
1200
1201 struct user_entry_type *find_entry_type(char *name)
1202 {
1203 struct user_entry_type *p;
1204
1205 for (p = entry_type_list; p; p = p->next) {
1206 if (!strcasecmp(name, p->name))
1207 return p;
1208 }
1209 return NULL;
1210 }
1211
1212 struct user_entry *find_user_entry(struct user_entry_type *et,
1213 struct userrec *u)
1214 {
1215 struct user_entry **e, *t;
1216
1217 for (e = &(u->entries); *e; e = &((*e)->next)) {
1218 if (((*e)->type == et) ||
1219 ((*e)->name && !strcasecmp((*e)->name, et->name))) {
1220 t = *e;
1221 *e = t->next;
1222 t->next = u->entries;
1223 u->entries = t;
1224 return t;
1225 }
1226 }
1227 return NULL;
1228 }
1229
1230 void *get_user(struct user_entry_type *et, struct userrec *u)
1231 {
1232 struct user_entry *e;
1233
1234 if (u && (e = find_user_entry(et, u)))
1235 return et->get(u, e);
1236 return 0;
1237 }
1238
1239 int set_user(struct user_entry_type *et, struct userrec *u, void *d)
1240 {
1241 struct user_entry *e;
1242 int r;
1243
1244 if (!u || !et)
1245 return 0;
1246
1247 if (!(e = find_user_entry(et, u))) {
1248 e = user_malloc(sizeof(struct user_entry));
1249
1250 e->type = et;
1251 e->name = NULL;
1252 e->u.list = NULL;
1253 list_insert((&(u->entries)), e);
1254 }
1255 r = et->set(u, e, d);
1256 if (!e->u.list) {
1257 list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
1258 nfree(e);
1259 }
1260 return r;
1261 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23