/[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.3 - (show annotations) (download) (as text)
Fri Oct 15 10:44:57 1999 UTC (19 years, 9 months ago) by fabian
Branch: MAIN
Changes since 1.2: +249 -259 lines
File MIME type: text/x-chdr
resync 1.3: 939574072->939863113

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23