/[cvs]/eggdrop1.4/src/userent.c
ViewVC logotype

Contents of /eggdrop1.4/src/userent.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1.1.1 - (show annotations) (download) (as text) (vendor branch)
Wed Jun 23 19:51:33 1999 UTC (22 years, 4 months ago) by segfault
Branch: eggdev
CVS Tags: start
Changes since 1.1: +0 -0 lines
File MIME type: text/x-chdr
Eggdrop 1.3.28 CVS Code

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23