/[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.21 - (show annotations) (download) (as text)
Thu Jul 26 17:04:33 2001 UTC (18 years, 3 months ago) by drummer
Branch: MAIN
Changes since 1.20: +24 -13 lines
File MIME type: text/x-chdr
added adns dir

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23