/[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.37 - (show annotations) (download) (as text)
Tue Feb 18 10:37:18 2003 UTC (16 years, 5 months ago) by stdarg
Branch: MAIN
Changes since 1.36: +0 -1 lines
File MIME type: text/x-chdr
*** empty log message ***

1 /*
2 * userent.c --
3 *
4 * user-entry handling, new stylem more versatile.
5 */
6
7 #include "main.h"
8 #include "users.h"
9 #include "logfile.h"
10 #include "modules.h" /* encrypt_pass */
11 #include "tcl.h" /* Tcl_Free */
12 #include "flags.h" /* USER_* */
13 #include "dccutil.h" /* dprintf_eggdrop */
14 #include "userrec.h" /* addhost_by_handle */
15 #include "userent.h" /* prototypes */
16
17 extern struct userrec *userlist;
18 extern struct dcc_t *dcc;
19 extern Tcl_Interp *interp;
20 extern char whois_fields[];
21
22 static struct user_entry_type *entry_type_list;
23
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 free(t->extra);
46 free(t);
47 t = u;
48 }
49 }
50
51 int def_unpack(struct userrec *u, struct user_entry *e)
52 {
53 char *tmp;
54
55 tmp = e->u.list->extra;
56 e->u.list->extra = NULL;
57 list_type_kill(e->u.list);
58 e->u.string = tmp;
59 return 1;
60 }
61
62 int def_pack(struct userrec *u, struct user_entry *e)
63 {
64 char *tmp;
65
66 tmp = e->u.string;
67 e->u.list = malloc(sizeof(struct list_type));
68 e->u.list->next = NULL;
69 e->u.list->extra = tmp;
70 return 1;
71 }
72
73 int def_kill(struct user_entry *e)
74 {
75 free(e->u.string);
76 free(e);
77 return 1;
78 }
79
80 int def_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
81 {
82 if (fprintf(f, "--%s %s\n", e->type->name, e->u.string) == EOF)
83 return 0;
84 return 1;
85 }
86
87 void *def_get(struct userrec *u, struct user_entry *e)
88 {
89 return e->u.string;
90 }
91
92 int def_set(struct userrec *u, struct user_entry *e, void *buf)
93 {
94 char *string = (char *) buf;
95
96 if (string && !string[0])
97 string = NULL;
98 if (!string && !e->u.string)
99 return 1;
100 if (string) {
101 int l = strlen (string);
102 char *i;
103
104 if (l > 160)
105 l = 160;
106
107 e->u.string = realloc(e->u.string, l + 1);
108
109 strlcpy (e->u.string, string, l + 1);
110
111 for (i = e->u.string; *i; i++)
112 /* Allow bold, inverse, underline, color text here...
113 * But never add cr or lf!! --rtc
114 */
115 if ((unsigned int) *i < 32 && !strchr ("\002\003\026\037", *i))
116 *i = '?';
117 } else { /* string == NULL && e->u.string != NULL */
118 free_null(e->u.string);
119 }
120 return 1;
121 }
122
123 int def_gotshare(struct userrec *u, struct user_entry *e,
124 char *data, int idx)
125 {
126 return 0;
127 }
128
129 int def_tcl_get(Tcl_Interp * interp, struct userrec *u,
130 struct user_entry *e, int argc, char **argv)
131 {
132 Tcl_AppendResult(interp, e->u.string, NULL);
133 return TCL_OK;
134 }
135
136 int def_tcl_set(Tcl_Interp * irp, struct userrec *u,
137 struct user_entry *e, int argc, char **argv)
138 {
139 BADARGS(4, 4, " handle type setting");
140 e->type->set(u, e, argv[3]);
141 return TCL_OK;
142 }
143
144 void def_display(int idx, struct user_entry *e)
145 {
146 dprintf(idx, " %s: %s\n", e->type->name, e->u.string);
147 }
148
149 int def_dupuser(struct userrec *new, struct userrec *old,
150 struct user_entry *e)
151 {
152 return set_user(e->type, new, e->u.string);
153 }
154
155 static void comment_display(int idx, struct user_entry *e)
156 {
157 if (dcc[idx].user && (dcc[idx].user->flags & USER_MASTER))
158 dprintf(idx, " COMMENT: %.70s\n", e->u.string);
159 }
160
161 struct user_entry_type USERENTRY_COMMENT =
162 {
163 0, /* always 0 ;) */
164 def_gotshare,
165 def_dupuser,
166 def_unpack,
167 def_pack,
168 def_write_userfile,
169 def_kill,
170 def_get,
171 def_set,
172 def_tcl_get,
173 def_tcl_set,
174 comment_display,
175 "COMMENT"
176 };
177
178 struct user_entry_type USERENTRY_INFO =
179 {
180 0, /* always 0 ;) */
181 def_gotshare,
182 def_dupuser,
183 def_unpack,
184 def_pack,
185 def_write_userfile,
186 def_kill,
187 def_get,
188 def_set,
189 def_tcl_get,
190 def_tcl_set,
191 def_display,
192 "INFO"
193 };
194
195 int pass_set(struct userrec *u, struct user_entry *e, void *buf)
196 {
197 char new[32];
198 register char *pass = buf;
199
200 if (e->u.extra)
201 free(e->u.extra);
202 if (!pass || !pass[0] || (pass[0] == '-'))
203 e->u.extra = NULL;
204 else {
205 unsigned char *p = (unsigned char *) pass;
206
207 if (strlen(pass) > 15)
208 pass[15] = 0;
209 while (*p) {
210 if ((*p <= 32) || (*p == 127))
211 *p = '?';
212 p++;
213 }
214 if ((u->flags & USER_BOT) || (pass[0] == '+'))
215 strcpy(new, pass);
216 else
217 encrypt_pass(pass, new);
218 e->u.extra = strdup(new);
219 }
220 return 1;
221 }
222
223 static int pass_tcl_set(Tcl_Interp * irp, struct userrec *u,
224 struct user_entry *e, int argc, char **argv)
225 {
226 BADARGS(3, 4, " handle PASS ?newpass?");
227 pass_set(u, e, argv[3]);
228 return TCL_OK;
229 }
230
231 struct user_entry_type USERENTRY_PASS =
232 {
233 0,
234 def_gotshare,
235 0,
236 def_unpack,
237 def_pack,
238 def_write_userfile,
239 def_kill,
240 def_get,
241 pass_set,
242 def_tcl_get,
243 pass_tcl_set,
244 0,
245 "PASS"
246 };
247
248 static int laston_unpack(struct userrec *u, struct user_entry *e)
249 {
250 char *par, *arg;
251 struct laston_info *li;
252
253 par = e->u.list->extra;
254 arg = newsplit (&par);
255 if (!par[0])
256 par = "???";
257 li = malloc(sizeof(struct laston_info));
258 li->lastonplace = malloc(strlen(par) + 1);
259 li->laston = atoi(arg);
260 strcpy(li->lastonplace, par);
261 list_type_kill(e->u.list);
262 e->u.extra = li;
263 return 1;
264 }
265
266 static int laston_pack(struct userrec *u, struct user_entry *e)
267 {
268 char work[1024];
269 struct laston_info *li;
270
271 li = (struct laston_info *) e->u.extra;
272 sprintf(work, "%lu %s", li->laston, li->lastonplace);
273 e->u.list = malloc(sizeof(struct list_type));
274 e->u.list->next = NULL;
275 e->u.list->extra = strdup(work);
276 free(li->lastonplace);
277 free(li);
278 return 1;
279 }
280
281 static int laston_write_userfile(FILE * f,
282 struct userrec *u,
283 struct user_entry *e)
284 {
285 struct laston_info *li = (struct laston_info *) e->u.extra;
286
287 if (fprintf(f, "--LASTON %lu %s\n", li->laston,
288 li->lastonplace ? li->lastonplace : "") == EOF)
289 return 0;
290 return 1;
291 }
292
293 static int laston_kill(struct user_entry *e)
294 {
295 if (((struct laston_info *) (e->u.extra))->lastonplace)
296 free(((struct laston_info *) (e->u.extra))->lastonplace);
297 free(e->u.extra);
298 free(e);
299 return 1;
300 }
301
302 static int laston_set(struct userrec *u, struct user_entry *e, void *buf)
303 {
304 struct laston_info *li = (struct laston_info *) e->u.extra;
305
306 if (li != buf) {
307 if (li) {
308 free(li->lastonplace);
309 free(li);
310 }
311
312 li = e->u.extra = buf;
313 }
314 return 1;
315 }
316
317 static int laston_tcl_get(Tcl_Interp * irp, struct userrec *u,
318 struct user_entry *e, int argc, char **argv)
319 {
320 struct laston_info *li = (struct laston_info *) e->u.extra;
321 char number[20];
322 struct chanuserrec *cr;
323
324 BADARGS(3, 4, " handle LASTON ?channel?");
325 if (argc == 4) {
326 for (cr = u->chanrec; cr; cr = cr->next)
327 if (!irccmp(cr->channel, argv[3])) {
328 Tcl_AppendResult(irp, int_to_base10(cr->laston), NULL);
329 break;
330 }
331 if (!cr)
332 Tcl_AppendResult(irp, "0", NULL);
333 } else {
334 sprintf(number, "%lu ", li->laston);
335 Tcl_AppendResult(irp, number, li->lastonplace, NULL);
336 }
337 return TCL_OK;
338 }
339
340 static int laston_tcl_set(Tcl_Interp * irp, struct userrec *u,
341 struct user_entry *e, int argc, char **argv)
342 {
343 struct laston_info *li;
344 struct chanuserrec *cr;
345
346 BADARGS(4, 5, " handle LASTON time ?place?");
347
348 if ((argc == 5) && argv[4][0] && strchr(CHANMETA, argv[4][0])) {
349 /* Search for matching channel */
350 for (cr = u->chanrec; cr; cr = cr->next)
351 if (!irccmp(cr->channel, argv[4])) {
352 cr->laston = atoi(argv[3]);
353 break;
354 }
355 }
356 /* Save globally */
357 li = malloc(sizeof(struct laston_info));
358
359 if (argc == 5)
360 li->lastonplace = strdup(argv[4]);
361 else
362 li->lastonplace = calloc(1, 1);
363
364 li->laston = atoi(argv[3]);
365 set_user(&USERENTRY_LASTON, u, li);
366 return TCL_OK;
367 }
368
369 static int laston_dupuser(struct userrec *new, struct userrec *old,
370 struct user_entry *e)
371 {
372 struct laston_info *li = e->u.extra, *li2;
373
374 if (li) {
375 li2 = malloc(sizeof(struct laston_info));
376
377 li2->laston = li->laston;
378 li2->lastonplace = strdup(li->lastonplace);
379 return set_user(&USERENTRY_LASTON, new, li2);
380 }
381 return 0;
382 }
383
384 struct user_entry_type USERENTRY_LASTON =
385 {
386 0, /* always 0 ;) */
387 0,
388 laston_dupuser,
389 laston_unpack,
390 laston_pack,
391 laston_write_userfile,
392 laston_kill,
393 def_get,
394 laston_set,
395 laston_tcl_get,
396 laston_tcl_set,
397 0,
398 "LASTON"
399 };
400
401 static int botaddr_unpack(struct userrec *u, struct user_entry *e)
402 {
403 char *p = NULL, *q;
404 struct bot_addr *bi;
405
406 bi = calloc(1, sizeof(struct bot_addr));
407 q = (e->u.list->extra);
408 p = strdup(q);
409 if (!(q = strchr_unescape(p, ':', '\\')))
410 bi->address = strdup(p);
411 else {
412 bi->address = strdup(p);
413 bi->telnet_port = atoi(q);
414 if ((q = strchr(q, '/')))
415 bi->relay_port = atoi(q + 1);
416 }
417 free(p);
418 if (!bi->telnet_port)
419 bi->telnet_port = 3333;
420 if (!bi->relay_port)
421 bi->relay_port = bi->telnet_port;
422 list_type_kill(e->u.list);
423 e->u.extra = bi;
424 return 1;
425 }
426
427 static int botaddr_pack(struct userrec *u, struct user_entry *e)
428 {
429 char work[1024];
430 struct bot_addr *bi;
431 char *tmp;
432
433 bi = (struct bot_addr *) e->u.extra;
434 simple_sprintf(work, "%s:%u/%u",
435 (tmp = str_escape(bi->address, ':', '\\')),
436 bi->telnet_port, bi->relay_port);
437 free(tmp);
438 e->u.list = malloc(sizeof(struct list_type));
439 e->u.list->next = NULL;
440 e->u.list->extra = strdup(work);
441 free(bi->address);
442 free(bi);
443 return 1;
444 }
445
446 static int botaddr_kill(struct user_entry *e)
447 {
448 free(((struct bot_addr *) (e->u.extra))->address);
449 free(e->u.extra);
450 free(e);
451 return 1;
452 }
453
454 static int botaddr_write_userfile(FILE *f, struct userrec *u,
455 struct user_entry *e)
456 {
457 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
458 register char *tmp;
459 register int res;
460
461 res = (fprintf(f, "--%s %s:%u/%u\n", e->type->name,
462 (tmp = str_escape(bi->address, ':', '\\')),
463 bi->telnet_port, bi->relay_port) != EOF);
464 free(tmp);
465 return res;
466 }
467
468 static int botaddr_set(struct userrec *u, struct user_entry *e, void *buf)
469 {
470 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
471
472 if (!bi && !buf)
473 return 1;
474 if (bi != buf) {
475 if (bi) {
476 free(bi->address);
477 free(bi);
478 }
479 bi = e->u.extra = buf;
480 }
481 return 1;
482 }
483
484 static int botaddr_tcl_get(Tcl_Interp *interp, struct userrec *u,
485 struct user_entry *e, int argc, char **argv)
486 {
487 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
488 char number[20];
489
490 sprintf(number, " %d", bi->telnet_port);
491 Tcl_AppendResult(interp, bi->address, number, NULL);
492 sprintf(number, " %d", bi->relay_port);
493 Tcl_AppendResult(interp, number, NULL);
494 return TCL_OK;
495 }
496
497 static int botaddr_tcl_set(Tcl_Interp *irp, struct userrec *u,
498 struct user_entry *e, int argc, char **argv)
499 {
500 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
501
502 BADARGS(4, 6, " handle type address ?telnetport ?relayport??");
503 if (u->flags & USER_BOT) {
504 /* Silently ignore for users */
505 if (!bi) {
506 bi = calloc(1, sizeof(struct bot_addr));
507 } else {
508 free(bi->address);
509 }
510 bi->address = strdup(argv[3]);
511 if (argc > 4)
512 bi->telnet_port = atoi(argv[4]);
513 if (argc > 5)
514 bi->relay_port = atoi(argv[5]);
515 if (!bi->telnet_port)
516 bi->telnet_port = 3333;
517 if (!bi->relay_port)
518 bi->relay_port = bi->telnet_port;
519 botaddr_set(u, e, bi);
520 }
521 return TCL_OK;
522 }
523
524 static void botaddr_display(int idx, struct user_entry *e)
525 {
526 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
527
528 dprintf(idx, " ADDRESS: %.70s\n", bi->address);
529 dprintf(idx, " users: %d, bots: %d\n", bi->relay_port, bi->telnet_port);
530 }
531
532 static int botaddr_gotshare(struct userrec *u, struct user_entry *e,
533 char *buf, int idx)
534 {
535 return 0;
536 }
537
538 static int botaddr_dupuser(struct userrec *new, struct userrec *old,
539 struct user_entry *e)
540 {
541 if (old->flags & USER_BOT) {
542 struct bot_addr *bi = e->u.extra, *bi2;
543
544 if (bi) {
545 bi2 = malloc(sizeof(struct bot_addr));
546
547 bi2->telnet_port = bi->telnet_port;
548 bi2->relay_port = bi->relay_port;
549 bi2->address = strdup(bi->address);
550 return set_user(&USERENTRY_BOTADDR, new, bi2);
551 }
552 }
553 return 0;
554 }
555
556 struct user_entry_type USERENTRY_BOTADDR =
557 {
558 0, /* always 0 ;) */
559 botaddr_gotshare,
560 botaddr_dupuser,
561 botaddr_unpack,
562 botaddr_pack,
563 botaddr_write_userfile,
564 botaddr_kill,
565 def_get,
566 botaddr_set,
567 botaddr_tcl_get,
568 botaddr_tcl_set,
569 botaddr_display,
570 "BOTADDR"
571 };
572
573 int xtra_set(struct userrec *u, struct user_entry *e, void *buf)
574 {
575 struct xtra_key *curr, *old = NULL, *new = buf;
576
577 for (curr = e->u.extra; curr; curr = curr->next) {
578 if (curr->key && !strcasecmp(curr->key, new->key)) {
579 old = curr;
580 break;
581 }
582 }
583 if (!old && (!new->data || !new->data[0])) {
584 /* Delete non-existant entry -- doh ++rtc */
585 free(new->key);
586 if (new->data)
587 free(new->data);
588 free(new);
589 return TCL_OK;
590 }
591
592 if ((old && old != new) || !new->data || !new->data[0]) {
593 list_delete((struct list_type **) (&e->u.extra),
594 (struct list_type *) old);
595 free(old->key);
596 free(old->data);
597 free(old);
598 }
599 if (old != new && new->data) {
600 if (new->data[0])
601 list_insert((&e->u.extra), new) /* do not add a ';' here */
602 } else {
603 if (new->data)
604 free(new->data);
605 free(new->key);
606 free(new);
607 }
608 return TCL_OK;
609 }
610
611 static int xtra_tcl_set(Tcl_Interp * irp, struct userrec *u,
612 struct user_entry *e, int argc, char **argv)
613 {
614 struct xtra_key *xk;
615 int l;
616
617 BADARGS(4, 5, " handle type key ?value?");
618 xk = calloc(1, sizeof(struct xtra_key));
619 l = strlen(argv[3]);
620 if (l > 500)
621 l = 500;
622 xk->key = malloc(l + 1);
623 strlcpy(xk->key, argv[3], l + 1);
624
625 if (argc == 5) {
626 int k = strlen(argv[4]);
627
628 if (k > 500 - l)
629 k = 500 - l;
630 xk->data = malloc(k + 1);
631 strlcpy(xk->data, argv[4], k + 1);
632 }
633 xtra_set(u, e, xk);
634 return TCL_OK;
635 }
636
637 int xtra_unpack(struct userrec *u, struct user_entry *e)
638 {
639 struct list_type *curr, *head;
640 struct xtra_key *t;
641 char *key, *data;
642
643 head = curr = e->u.list;
644 e->u.extra = NULL;
645 while (curr) {
646 t = malloc(sizeof(struct xtra_key));
647
648 data = curr->extra;
649 key = newsplit(&data);
650 if (data[0]) {
651 t->key = strdup(key);
652 t->data = strdup(data);
653 list_insert((&e->u.extra), t);
654 }
655 curr = curr->next;
656 }
657 list_type_kill(head);
658 return 1;
659 }
660
661 static int xtra_pack(struct userrec *u, struct user_entry *e)
662 {
663 struct list_type *t;
664 struct xtra_key *curr, *next;
665
666 curr = e->u.extra;
667 e->u.list = NULL;
668 while (curr) {
669 t = malloc(sizeof(struct list_type));
670 t->extra = malloc(strlen(curr->key) + strlen(curr->data) + 4);
671 sprintf(t->extra, "%s %s", curr->key, curr->data);
672 list_insert((&e->u.list), t);
673 next = curr->next;
674 free(curr->key);
675 free(curr->data);
676 free(curr);
677 curr = next;
678 }
679 return 1;
680 }
681
682 static void xtra_display(int idx, struct user_entry *e)
683 {
684 int code, lc, j;
685 struct xtra_key *xk;
686 char **list;
687
688 code = Tcl_SplitList(interp, whois_fields, &lc, &list);
689 if (code == TCL_ERROR)
690 return;
691 /* Scan thru xtra field, searching for matches */
692 for (xk = e->u.extra; xk; xk = xk->next) {
693 /* Ok, it's a valid xtra field entry */
694 for (j = 0; j < lc; j++) {
695 if (!strcasecmp(list[j], xk->key))
696 dprintf(idx, " %s: %s\n", xk->key, xk->data);
697 }
698 }
699 Tcl_Free((char *) list);
700 }
701
702 static int xtra_gotshare(struct userrec *u, struct user_entry *e,
703 char *buf, int idx)
704 {
705 return 0;
706 }
707
708 static int xtra_dupuser(struct userrec *new, struct userrec *old,
709 struct user_entry *e)
710 {
711 struct xtra_key *x1, *x2;
712
713 for (x1 = e->u.extra; x1; x1 = x1->next) {
714 x2 = malloc(sizeof(struct xtra_key));
715
716 x2->key = strdup(x1->key);
717 x2->data = strdup(x1->data);
718 set_user(&USERENTRY_XTRA, new, x2);
719 }
720 return 1;
721 }
722
723 static int xtra_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
724 {
725 struct xtra_key *x;
726
727 for (x = e->u.extra; x; x = x->next)
728 if (fprintf(f, "--XTRA %s %s\n", x->key, x->data) == EOF)
729 return 0;
730 return 1;
731 }
732
733 int xtra_kill(struct user_entry *e)
734 {
735 struct xtra_key *x, *y;
736
737 for (x = e->u.extra; x; x = y) {
738 y = x->next;
739 free(x->key);
740 free(x->data);
741 free(x);
742 }
743 free(e);
744 return 1;
745 }
746
747 static int xtra_tcl_get(Tcl_Interp *irp, struct userrec *u,
748 struct user_entry *e, int argc, char **argv)
749 {
750 struct xtra_key *x;
751
752 BADARGS(3, 4, " handle XTRA ?key?");
753 if (argc == 4) {
754 for (x = e->u.extra; x; x = x->next)
755 if (!strcasecmp(argv[3], x->key)) {
756 Tcl_AppendResult(irp, x->data, NULL);
757 return TCL_OK;
758 }
759 return TCL_OK;
760 }
761 for (x = e->u.extra; x; x = x->next) {
762 char *p, *list[2];
763
764 list[0] = x->key;
765 list[1] = x->data;
766 p = Tcl_Merge(2, list);
767 Tcl_AppendElement(irp, p);
768 Tcl_Free((char *) p);
769 }
770 return TCL_OK;
771 }
772
773 struct user_entry_type USERENTRY_XTRA =
774 {
775 0,
776 xtra_gotshare,
777 xtra_dupuser,
778 xtra_unpack,
779 xtra_pack,
780 xtra_write_userfile,
781 xtra_kill,
782 def_get,
783 xtra_set,
784 xtra_tcl_get,
785 xtra_tcl_set,
786 xtra_display,
787 "XTRA"
788 };
789
790 static int hosts_dupuser(struct userrec *new, struct userrec *old,
791 struct user_entry *e)
792 {
793 struct list_type *h;
794
795 for (h = e->u.extra; h; h = h->next)
796 set_user(&USERENTRY_HOSTS, new, h->extra);
797 return 1;
798 }
799
800 static int hosts_null(struct userrec *u, struct user_entry *e)
801 {
802 return 1;
803 }
804
805 static int hosts_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
806 {
807 struct list_type *h;
808
809 for (h = e->u.extra; h; h = h->next)
810 if (fprintf(f, "--HOSTS %s\n", h->extra) == EOF)
811 return 0;
812 return 1;
813 }
814
815 static int hosts_kill(struct user_entry *e)
816 {
817 list_type_kill(e->u.list);
818 free(e);
819 return 1;
820 }
821
822 static void hosts_display(int idx, struct user_entry *e)
823 {
824 char s[1024];
825 struct list_type *q;
826
827 s[0] = 0;
828 strcpy(s, " HOSTS: ");
829 for (q = e->u.list; q; q = q->next) {
830 if (s[0] && !s[9])
831 strcat(s, q->extra);
832 else if (!s[0])
833 sprintf(s, " %s", q->extra);
834 else {
835 if (strlen(s) + strlen(q->extra) + 2 > 65) {
836 dprintf(idx, "%s\n", s);
837 sprintf(s, " %s", q->extra);
838 } else {
839 strcat(s, ", ");
840 strcat(s, q->extra);
841 }
842 }
843 }
844 if (s[0])
845 dprintf(idx, "%s\n", s);
846 }
847
848 static int hosts_set(struct userrec *u, struct user_entry *e, void *buf)
849 {
850 if (!buf || !strcasecmp(buf, "none")) {
851 /* When the bot crashes, it's in this part, not in the 'else' part */
852 list_type_kill(e->u.list);
853 e->u.list = NULL;
854 } else {
855 char *host = buf, *p = strchr(host, ',');
856 struct list_type **t;
857
858 /* Can't have ,'s in hostmasks */
859 while (p) {
860 *p = '?';
861 p = strchr(host, ',');
862 }
863 /* fred1: check for redundant hostmasks with
864 * controversial "superpenis" algorithm ;) */
865 /* I'm surprised Raistlin hasn't gotten involved in this controversy */
866 t = &(e->u.list);
867 while (*t) {
868 if (wild_match(host, (*t)->extra)) {
869 struct list_type *u;
870
871 u = *t;
872 *t = (*t)->next;
873 if (u->extra)
874 free(u->extra);
875 free(u);
876 } else
877 t = &((*t)->next);
878 }
879 *t = malloc(sizeof(struct list_type));
880
881 (*t)->next = NULL;
882 (*t)->extra = strdup(host);
883 }
884 return 1;
885 }
886
887 static int hosts_tcl_get(Tcl_Interp *irp, struct userrec *u,
888 struct user_entry *e, int argc, char **argv)
889 {
890 struct list_type *x;
891
892 BADARGS(3, 3, " handle HOSTS");
893 for (x = e->u.list; x; x = x->next)
894 Tcl_AppendElement(irp, x->extra);
895 return TCL_OK;
896 }
897
898 static int hosts_tcl_set(Tcl_Interp * irp, struct userrec *u,
899 struct user_entry *e, int argc, char **argv)
900 {
901 BADARGS(3, 4, " handle HOSTS ?host?");
902 if (argc == 4)
903 addhost_by_handle(u->handle, argv[3]);
904 else
905 addhost_by_handle(u->handle, "none"); /* drummer */
906 return TCL_OK;
907 }
908
909 static int hosts_gotshare(struct userrec *u, struct user_entry *e,
910 char *buf, int idx)
911 {
912 return 0;
913 }
914
915 struct user_entry_type USERENTRY_HOSTS =
916 {
917 0,
918 hosts_gotshare,
919 hosts_dupuser,
920 hosts_null,
921 hosts_null,
922 hosts_write_userfile,
923 hosts_kill,
924 def_get,
925 hosts_set,
926 hosts_tcl_get,
927 hosts_tcl_set,
928 hosts_display,
929 "HOSTS"
930 };
931
932 int list_append(struct list_type **h, struct list_type *i)
933 {
934 for (; *h; h = &((*h)->next));
935 *h = i;
936 return 1;
937 }
938
939 int list_delete(struct list_type **h, struct list_type *i)
940 {
941 for (; *h; h = &((*h)->next))
942 if (*h == i) {
943 *h = i->next;
944 return 1;
945 }
946 return 0;
947 }
948
949 int list_contains(struct list_type *h, struct list_type *i)
950 {
951 for (; h; h = h->next)
952 if (h == i) {
953 return 1;
954 }
955 return 0;
956 }
957
958 int add_entry_type(struct user_entry_type *type)
959 {
960 struct userrec *u;
961
962 list_insert(&entry_type_list, type);
963 for (u = userlist; u; u = u->next) {
964 struct user_entry *e = find_user_entry(type, u);
965
966 if (e && e->name) {
967 e->type = type;
968 e->type->unpack(u, e);
969 free_null(e->name);
970 }
971 }
972 return 1;
973 }
974
975 int del_entry_type(struct user_entry_type *type)
976 {
977 struct userrec *u;
978
979 for (u = userlist; u; u = u->next) {
980 struct user_entry *e = find_user_entry(type, u);
981
982 if (e && !e->name) {
983 e->type->pack(u, e);
984 e->name = strdup(e->type->name);
985 e->type = NULL;
986 }
987 }
988 return list_delete((struct list_type **) &entry_type_list,
989 (struct list_type *) type);
990 }
991
992 struct user_entry_type *find_entry_type(char *name)
993 {
994 struct user_entry_type *p;
995
996 for (p = entry_type_list; p; p = p->next) {
997 if (!strcasecmp(name, p->name))
998 return p;
999 }
1000 return NULL;
1001 }
1002
1003 struct user_entry *find_user_entry(struct user_entry_type *et,
1004 struct userrec *u)
1005 {
1006 struct user_entry **e, *t;
1007
1008 for (e = &(u->entries); *e; e = &((*e)->next)) {
1009 if (((*e)->type == et) ||
1010 ((*e)->name && !strcasecmp((*e)->name, et->name))) {
1011 t = *e;
1012 *e = t->next;
1013 t->next = u->entries;
1014 u->entries = t;
1015 return t;
1016 }
1017 }
1018 return NULL;
1019 }
1020
1021 void *get_user(struct user_entry_type *et, struct userrec *u)
1022 {
1023 struct user_entry *e;
1024
1025 if (u && (e = find_user_entry(et, u)))
1026 return et->get(u, e);
1027 return 0;
1028 }
1029
1030 int set_user(struct user_entry_type *et, struct userrec *u, void *d)
1031 {
1032 struct user_entry *e;
1033 int r;
1034
1035 if (!u || !et)
1036 return 0;
1037
1038 if (!(e = find_user_entry(et, u))) {
1039 e = malloc(sizeof(struct user_entry));
1040
1041 e->type = et;
1042 e->name = NULL;
1043 e->u.list = NULL;
1044 list_insert((&(u->entries)), e);
1045 }
1046 r = et->set(u, e, d);
1047 if (!e->u.list) {
1048 list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
1049 free(e);
1050 }
1051 return r;
1052 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23