/[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.38 - (show annotations) (download) (as text)
Tue Feb 25 06:52:19 2003 UTC (16 years, 4 months ago) by stdarg
Branch: MAIN
Changes since 1.37: +17 -228 lines
File MIME type: text/x-chdr
* Well, I think Tcl is finally removed from the core (except for detection/configuration).

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 "flags.h" /* USER_* */
12 #include "dccutil.h" /* dprintf_eggdrop */
13 #include "userrec.h" /* addhost_by_handle */
14 #include "userent.h" /* prototypes */
15
16 extern struct userrec *userlist;
17 extern struct dcc_t *dcc;
18 extern char whois_fields[];
19
20 static struct user_entry_type *entry_type_list;
21
22
23 void init_userent()
24 {
25 entry_type_list = 0;
26 add_entry_type(&USERENTRY_COMMENT);
27 add_entry_type(&USERENTRY_XTRA);
28 add_entry_type(&USERENTRY_INFO);
29 add_entry_type(&USERENTRY_LASTON);
30 add_entry_type(&USERENTRY_BOTADDR);
31 add_entry_type(&USERENTRY_PASS);
32 add_entry_type(&USERENTRY_HOSTS);
33 add_entry_type(&USERENTRY_BOTFL);
34 }
35
36 void list_type_kill(struct list_type *t)
37 {
38 struct list_type *u;
39
40 while (t) {
41 u = t->next;
42 if (t->extra)
43 free(t->extra);
44 free(t);
45 t = u;
46 }
47 }
48
49 int def_unpack(struct userrec *u, struct user_entry *e)
50 {
51 char *tmp;
52
53 tmp = e->u.list->extra;
54 e->u.list->extra = NULL;
55 list_type_kill(e->u.list);
56 e->u.string = tmp;
57 return 1;
58 }
59
60 int def_pack(struct userrec *u, struct user_entry *e)
61 {
62 char *tmp;
63
64 tmp = e->u.string;
65 e->u.list = malloc(sizeof(struct list_type));
66 e->u.list->next = NULL;
67 e->u.list->extra = tmp;
68 return 1;
69 }
70
71 int def_kill(struct user_entry *e)
72 {
73 free(e->u.string);
74 free(e);
75 return 1;
76 }
77
78 int def_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
79 {
80 if (fprintf(f, "--%s %s\n", e->type->name, e->u.string) == EOF)
81 return 0;
82 return 1;
83 }
84
85 void *def_get(struct userrec *u, struct user_entry *e)
86 {
87 return e->u.string;
88 }
89
90 int def_set(struct userrec *u, struct user_entry *e, void *buf)
91 {
92 char *string = (char *) buf;
93
94 if (string && !string[0])
95 string = NULL;
96 if (!string && !e->u.string)
97 return 1;
98 if (string) {
99 int l = strlen (string);
100 char *i;
101
102 if (l > 160)
103 l = 160;
104
105 e->u.string = realloc(e->u.string, l + 1);
106
107 strlcpy (e->u.string, string, l + 1);
108
109 for (i = e->u.string; *i; i++)
110 /* Allow bold, inverse, underline, color text here...
111 * But never add cr or lf!! --rtc
112 */
113 if ((unsigned int) *i < 32 && !strchr ("\002\003\026\037", *i))
114 *i = '?';
115 } else { /* string == NULL && e->u.string != NULL */
116 free_null(e->u.string);
117 }
118 return 1;
119 }
120
121 int def_gotshare(struct userrec *u, struct user_entry *e,
122 char *data, int idx)
123 {
124 return 0;
125 }
126
127 void def_display(int idx, struct user_entry *e)
128 {
129 dprintf(idx, " %s: %s\n", e->type->name, e->u.string);
130 }
131
132 int def_dupuser(struct userrec *new, struct userrec *old,
133 struct user_entry *e)
134 {
135 return set_user(e->type, new, e->u.string);
136 }
137
138 static void comment_display(int idx, struct user_entry *e)
139 {
140 if (dcc[idx].user && (dcc[idx].user->flags & USER_MASTER))
141 dprintf(idx, " COMMENT: %.70s\n", e->u.string);
142 }
143
144 struct user_entry_type USERENTRY_COMMENT =
145 {
146 0, /* always 0 ;) */
147 def_gotshare,
148 def_dupuser,
149 def_unpack,
150 def_pack,
151 def_write_userfile,
152 def_kill,
153 def_get,
154 def_set,
155 NULL,
156 NULL,
157 comment_display,
158 "COMMENT"
159 };
160
161 struct user_entry_type USERENTRY_INFO =
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 NULL,
173 NULL,
174 def_display,
175 "INFO"
176 };
177
178 int pass_set(struct userrec *u, struct user_entry *e, void *buf)
179 {
180 char new[32];
181 register char *pass = buf;
182
183 if (e->u.extra)
184 free(e->u.extra);
185 if (!pass || !pass[0] || (pass[0] == '-'))
186 e->u.extra = NULL;
187 else {
188 unsigned char *p = (unsigned char *) pass;
189
190 if (strlen(pass) > 15)
191 pass[15] = 0;
192 while (*p) {
193 if ((*p <= 32) || (*p == 127))
194 *p = '?';
195 p++;
196 }
197 if ((u->flags & USER_BOT) || (pass[0] == '+'))
198 strcpy(new, pass);
199 else
200 encrypt_pass(pass, new);
201 e->u.extra = strdup(new);
202 }
203 return 1;
204 }
205
206 struct user_entry_type USERENTRY_PASS =
207 {
208 0,
209 def_gotshare,
210 0,
211 def_unpack,
212 def_pack,
213 def_write_userfile,
214 def_kill,
215 def_get,
216 pass_set,
217 NULL,
218 NULL,
219 0,
220 "PASS"
221 };
222
223 static int laston_unpack(struct userrec *u, struct user_entry *e)
224 {
225 char *par, *arg;
226 struct laston_info *li;
227
228 par = e->u.list->extra;
229 arg = newsplit (&par);
230 if (!par[0])
231 par = "???";
232 li = malloc(sizeof(struct laston_info));
233 li->lastonplace = malloc(strlen(par) + 1);
234 li->laston = atoi(arg);
235 strcpy(li->lastonplace, par);
236 list_type_kill(e->u.list);
237 e->u.extra = li;
238 return 1;
239 }
240
241 static int laston_pack(struct userrec *u, struct user_entry *e)
242 {
243 char work[1024];
244 struct laston_info *li;
245
246 li = (struct laston_info *) e->u.extra;
247 sprintf(work, "%lu %s", li->laston, li->lastonplace);
248 e->u.list = malloc(sizeof(struct list_type));
249 e->u.list->next = NULL;
250 e->u.list->extra = strdup(work);
251 free(li->lastonplace);
252 free(li);
253 return 1;
254 }
255
256 static int laston_write_userfile(FILE * f,
257 struct userrec *u,
258 struct user_entry *e)
259 {
260 struct laston_info *li = (struct laston_info *) e->u.extra;
261
262 if (fprintf(f, "--LASTON %lu %s\n", li->laston,
263 li->lastonplace ? li->lastonplace : "") == EOF)
264 return 0;
265 return 1;
266 }
267
268 static int laston_kill(struct user_entry *e)
269 {
270 if (((struct laston_info *) (e->u.extra))->lastonplace)
271 free(((struct laston_info *) (e->u.extra))->lastonplace);
272 free(e->u.extra);
273 free(e);
274 return 1;
275 }
276
277 static int laston_set(struct userrec *u, struct user_entry *e, void *buf)
278 {
279 struct laston_info *li = (struct laston_info *) e->u.extra;
280
281 if (li != buf) {
282 if (li) {
283 free(li->lastonplace);
284 free(li);
285 }
286
287 li = e->u.extra = buf;
288 }
289 return 1;
290 }
291
292 static int laston_dupuser(struct userrec *new, struct userrec *old,
293 struct user_entry *e)
294 {
295 struct laston_info *li = e->u.extra, *li2;
296
297 if (li) {
298 li2 = malloc(sizeof(struct laston_info));
299
300 li2->laston = li->laston;
301 li2->lastonplace = strdup(li->lastonplace);
302 return set_user(&USERENTRY_LASTON, new, li2);
303 }
304 return 0;
305 }
306
307 struct user_entry_type USERENTRY_LASTON =
308 {
309 0, /* always 0 ;) */
310 0,
311 laston_dupuser,
312 laston_unpack,
313 laston_pack,
314 laston_write_userfile,
315 laston_kill,
316 def_get,
317 laston_set,
318 NULL,
319 NULL,
320 0,
321 "LASTON"
322 };
323
324 static int botaddr_unpack(struct userrec *u, struct user_entry *e)
325 {
326 char *p = NULL, *q;
327 struct bot_addr *bi;
328
329 bi = calloc(1, sizeof(struct bot_addr));
330 q = (e->u.list->extra);
331 p = strdup(q);
332 if (!(q = strchr_unescape(p, ':', '\\')))
333 bi->address = strdup(p);
334 else {
335 bi->address = strdup(p);
336 bi->telnet_port = atoi(q);
337 if ((q = strchr(q, '/')))
338 bi->relay_port = atoi(q + 1);
339 }
340 free(p);
341 if (!bi->telnet_port)
342 bi->telnet_port = 3333;
343 if (!bi->relay_port)
344 bi->relay_port = bi->telnet_port;
345 list_type_kill(e->u.list);
346 e->u.extra = bi;
347 return 1;
348 }
349
350 static int botaddr_pack(struct userrec *u, struct user_entry *e)
351 {
352 char work[1024];
353 struct bot_addr *bi;
354 char *tmp;
355
356 bi = (struct bot_addr *) e->u.extra;
357 simple_sprintf(work, "%s:%u/%u",
358 (tmp = str_escape(bi->address, ':', '\\')),
359 bi->telnet_port, bi->relay_port);
360 free(tmp);
361 e->u.list = malloc(sizeof(struct list_type));
362 e->u.list->next = NULL;
363 e->u.list->extra = strdup(work);
364 free(bi->address);
365 free(bi);
366 return 1;
367 }
368
369 static int botaddr_kill(struct user_entry *e)
370 {
371 free(((struct bot_addr *) (e->u.extra))->address);
372 free(e->u.extra);
373 free(e);
374 return 1;
375 }
376
377 static int botaddr_write_userfile(FILE *f, struct userrec *u,
378 struct user_entry *e)
379 {
380 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
381 register char *tmp;
382 register int res;
383
384 res = (fprintf(f, "--%s %s:%u/%u\n", e->type->name,
385 (tmp = str_escape(bi->address, ':', '\\')),
386 bi->telnet_port, bi->relay_port) != EOF);
387 free(tmp);
388 return res;
389 }
390
391 static int botaddr_set(struct userrec *u, struct user_entry *e, void *buf)
392 {
393 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
394
395 if (!bi && !buf)
396 return 1;
397 if (bi != buf) {
398 if (bi) {
399 free(bi->address);
400 free(bi);
401 }
402 bi = e->u.extra = buf;
403 }
404 return 1;
405 }
406
407 static void botaddr_display(int idx, struct user_entry *e)
408 {
409 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
410
411 dprintf(idx, " ADDRESS: %.70s\n", bi->address);
412 dprintf(idx, " users: %d, bots: %d\n", bi->relay_port, bi->telnet_port);
413 }
414
415 static int botaddr_gotshare(struct userrec *u, struct user_entry *e,
416 char *buf, int idx)
417 {
418 return 0;
419 }
420
421 static int botaddr_dupuser(struct userrec *new, struct userrec *old,
422 struct user_entry *e)
423 {
424 if (old->flags & USER_BOT) {
425 struct bot_addr *bi = e->u.extra, *bi2;
426
427 if (bi) {
428 bi2 = malloc(sizeof(struct bot_addr));
429
430 bi2->telnet_port = bi->telnet_port;
431 bi2->relay_port = bi->relay_port;
432 bi2->address = strdup(bi->address);
433 return set_user(&USERENTRY_BOTADDR, new, bi2);
434 }
435 }
436 return 0;
437 }
438
439 struct user_entry_type USERENTRY_BOTADDR =
440 {
441 0, /* always 0 ;) */
442 botaddr_gotshare,
443 botaddr_dupuser,
444 botaddr_unpack,
445 botaddr_pack,
446 botaddr_write_userfile,
447 botaddr_kill,
448 def_get,
449 botaddr_set,
450 NULL,
451 NULL,
452 botaddr_display,
453 "BOTADDR"
454 };
455
456 int xtra_set(struct userrec *u, struct user_entry *e, void *buf)
457 {
458 struct xtra_key *curr, *old = NULL, *new = buf;
459
460 for (curr = e->u.extra; curr; curr = curr->next) {
461 if (curr->key && !strcasecmp(curr->key, new->key)) {
462 old = curr;
463 break;
464 }
465 }
466 if (!old && (!new->data || !new->data[0])) {
467 /* Delete non-existant entry -- doh ++rtc */
468 free(new->key);
469 if (new->data)
470 free(new->data);
471 free(new);
472 return(0);
473 }
474
475 if ((old && old != new) || !new->data || !new->data[0]) {
476 list_delete((struct list_type **) (&e->u.extra),
477 (struct list_type *) old);
478 free(old->key);
479 free(old->data);
480 free(old);
481 }
482 if (old != new && new->data) {
483 if (new->data[0])
484 list_insert((&e->u.extra), new) /* do not add a ';' here */
485 } else {
486 if (new->data)
487 free(new->data);
488 free(new->key);
489 free(new);
490 }
491 return(0);
492 }
493
494 int xtra_unpack(struct userrec *u, struct user_entry *e)
495 {
496 struct list_type *curr, *head;
497 struct xtra_key *t;
498 char *key, *data;
499
500 head = curr = e->u.list;
501 e->u.extra = NULL;
502 while (curr) {
503 t = malloc(sizeof(struct xtra_key));
504
505 data = curr->extra;
506 key = newsplit(&data);
507 if (data[0]) {
508 t->key = strdup(key);
509 t->data = strdup(data);
510 list_insert((&e->u.extra), t);
511 }
512 curr = curr->next;
513 }
514 list_type_kill(head);
515 return 1;
516 }
517
518 static int xtra_pack(struct userrec *u, struct user_entry *e)
519 {
520 struct list_type *t;
521 struct xtra_key *curr, *next;
522
523 curr = e->u.extra;
524 e->u.list = NULL;
525 while (curr) {
526 t = malloc(sizeof(struct list_type));
527 t->extra = malloc(strlen(curr->key) + strlen(curr->data) + 4);
528 sprintf(t->extra, "%s %s", curr->key, curr->data);
529 list_insert((&e->u.list), t);
530 next = curr->next;
531 free(curr->key);
532 free(curr->data);
533 free(curr);
534 curr = next;
535 }
536 return 1;
537 }
538
539 static int xtra_gotshare(struct userrec *u, struct user_entry *e,
540 char *buf, int idx)
541 {
542 return 0;
543 }
544
545 static int xtra_dupuser(struct userrec *new, struct userrec *old,
546 struct user_entry *e)
547 {
548 struct xtra_key *x1, *x2;
549
550 for (x1 = e->u.extra; x1; x1 = x1->next) {
551 x2 = malloc(sizeof(struct xtra_key));
552
553 x2->key = strdup(x1->key);
554 x2->data = strdup(x1->data);
555 set_user(&USERENTRY_XTRA, new, x2);
556 }
557 return 1;
558 }
559
560 static int xtra_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
561 {
562 struct xtra_key *x;
563
564 for (x = e->u.extra; x; x = x->next)
565 if (fprintf(f, "--XTRA %s %s\n", x->key, x->data) == EOF)
566 return 0;
567 return 1;
568 }
569
570 int xtra_kill(struct user_entry *e)
571 {
572 struct xtra_key *x, *y;
573
574 for (x = e->u.extra; x; x = y) {
575 y = x->next;
576 free(x->key);
577 free(x->data);
578 free(x);
579 }
580 free(e);
581 return 1;
582 }
583
584 struct user_entry_type USERENTRY_XTRA =
585 {
586 0,
587 xtra_gotshare,
588 xtra_dupuser,
589 xtra_unpack,
590 xtra_pack,
591 xtra_write_userfile,
592 xtra_kill,
593 def_get,
594 xtra_set,
595 NULL,
596 NULL,
597 NULL,
598 "XTRA"
599 };
600
601 static int hosts_dupuser(struct userrec *new, struct userrec *old,
602 struct user_entry *e)
603 {
604 struct list_type *h;
605
606 for (h = e->u.extra; h; h = h->next)
607 set_user(&USERENTRY_HOSTS, new, h->extra);
608 return 1;
609 }
610
611 static int hosts_null(struct userrec *u, struct user_entry *e)
612 {
613 return 1;
614 }
615
616 static int hosts_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
617 {
618 struct list_type *h;
619
620 for (h = e->u.extra; h; h = h->next)
621 if (fprintf(f, "--HOSTS %s\n", h->extra) == EOF)
622 return 0;
623 return 1;
624 }
625
626 static int hosts_kill(struct user_entry *e)
627 {
628 list_type_kill(e->u.list);
629 free(e);
630 return 1;
631 }
632
633 static void hosts_display(int idx, struct user_entry *e)
634 {
635 char s[1024];
636 struct list_type *q;
637
638 s[0] = 0;
639 strcpy(s, " HOSTS: ");
640 for (q = e->u.list; q; q = q->next) {
641 if (s[0] && !s[9])
642 strcat(s, q->extra);
643 else if (!s[0])
644 sprintf(s, " %s", q->extra);
645 else {
646 if (strlen(s) + strlen(q->extra) + 2 > 65) {
647 dprintf(idx, "%s\n", s);
648 sprintf(s, " %s", q->extra);
649 } else {
650 strcat(s, ", ");
651 strcat(s, q->extra);
652 }
653 }
654 }
655 if (s[0])
656 dprintf(idx, "%s\n", s);
657 }
658
659 static int hosts_set(struct userrec *u, struct user_entry *e, void *buf)
660 {
661 if (!buf || !strcasecmp(buf, "none")) {
662 /* When the bot crashes, it's in this part, not in the 'else' part */
663 list_type_kill(e->u.list);
664 e->u.list = NULL;
665 } else {
666 char *host = buf, *p = strchr(host, ',');
667 struct list_type **t;
668
669 /* Can't have ,'s in hostmasks */
670 while (p) {
671 *p = '?';
672 p = strchr(host, ',');
673 }
674 /* fred1: check for redundant hostmasks with
675 * controversial "superpenis" algorithm ;) */
676 /* I'm surprised Raistlin hasn't gotten involved in this controversy */
677 t = &(e->u.list);
678 while (*t) {
679 if (wild_match(host, (*t)->extra)) {
680 struct list_type *u;
681
682 u = *t;
683 *t = (*t)->next;
684 if (u->extra)
685 free(u->extra);
686 free(u);
687 } else
688 t = &((*t)->next);
689 }
690 *t = malloc(sizeof(struct list_type));
691
692 (*t)->next = NULL;
693 (*t)->extra = strdup(host);
694 }
695 return 1;
696 }
697
698 static int hosts_gotshare(struct userrec *u, struct user_entry *e,
699 char *buf, int idx)
700 {
701 return 0;
702 }
703
704 struct user_entry_type USERENTRY_HOSTS =
705 {
706 0,
707 hosts_gotshare,
708 hosts_dupuser,
709 hosts_null,
710 hosts_null,
711 hosts_write_userfile,
712 hosts_kill,
713 def_get,
714 hosts_set,
715 NULL,
716 NULL,
717 hosts_display,
718 "HOSTS"
719 };
720
721 int list_append(struct list_type **h, struct list_type *i)
722 {
723 for (; *h; h = &((*h)->next));
724 *h = i;
725 return 1;
726 }
727
728 int list_delete(struct list_type **h, struct list_type *i)
729 {
730 for (; *h; h = &((*h)->next))
731 if (*h == i) {
732 *h = i->next;
733 return 1;
734 }
735 return 0;
736 }
737
738 int list_contains(struct list_type *h, struct list_type *i)
739 {
740 for (; h; h = h->next)
741 if (h == i) {
742 return 1;
743 }
744 return 0;
745 }
746
747 int add_entry_type(struct user_entry_type *type)
748 {
749 struct userrec *u;
750
751 list_insert(&entry_type_list, type);
752 for (u = userlist; u; u = u->next) {
753 struct user_entry *e = find_user_entry(type, u);
754
755 if (e && e->name) {
756 e->type = type;
757 e->type->unpack(u, e);
758 free_null(e->name);
759 }
760 }
761 return 1;
762 }
763
764 int del_entry_type(struct user_entry_type *type)
765 {
766 struct userrec *u;
767
768 for (u = userlist; u; u = u->next) {
769 struct user_entry *e = find_user_entry(type, u);
770
771 if (e && !e->name) {
772 e->type->pack(u, e);
773 e->name = strdup(e->type->name);
774 e->type = NULL;
775 }
776 }
777 return list_delete((struct list_type **) &entry_type_list,
778 (struct list_type *) type);
779 }
780
781 struct user_entry_type *find_entry_type(char *name)
782 {
783 struct user_entry_type *p;
784
785 for (p = entry_type_list; p; p = p->next) {
786 if (!strcasecmp(name, p->name))
787 return p;
788 }
789 return NULL;
790 }
791
792 struct user_entry *find_user_entry(struct user_entry_type *et,
793 struct userrec *u)
794 {
795 struct user_entry **e, *t;
796
797 for (e = &(u->entries); *e; e = &((*e)->next)) {
798 if (((*e)->type == et) ||
799 ((*e)->name && !strcasecmp((*e)->name, et->name))) {
800 t = *e;
801 *e = t->next;
802 t->next = u->entries;
803 u->entries = t;
804 return t;
805 }
806 }
807 return NULL;
808 }
809
810 void *get_user(struct user_entry_type *et, struct userrec *u)
811 {
812 struct user_entry *e;
813
814 if (u && (e = find_user_entry(et, u)))
815 return et->get(u, e);
816 return 0;
817 }
818
819 int set_user(struct user_entry_type *et, struct userrec *u, void *d)
820 {
821 struct user_entry *e;
822 int r;
823
824 if (!u || !et)
825 return 0;
826
827 if (!(e = find_user_entry(et, u))) {
828 e = malloc(sizeof(struct user_entry));
829
830 e->type = et;
831 e->name = NULL;
832 e->u.list = NULL;
833 list_insert((&(u->entries)), e);
834 }
835 r = et->set(u, e, d);
836 if (!e->u.list) {
837 list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
838 free(e);
839 }
840 return r;
841 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23