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

Contents of /eggdrop1.4/src/users.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 * users.c -- handles:
3 * testing and enforcing ignores
4 * adding and removing ignores
5 * listing ignores
6 * auto-linking bots
7 * sending and receiving a userfile from a bot
8 * listing users ('.whois' and '.match')
9 * reading the user file
10 *
11 * dprintf'ized, 9nov1995
12 */
13 /*
14 * This file is part of the eggdrop source code
15 * copyright (c) 1997 Robey Pointer
16 * and is distributed according to the GNU general public license.
17 * For full details, read the top of 'main.c' or the file called
18 * COPYING that was distributed with this code.
19 */
20
21 #include "main.h"
22 #include "users.h"
23 #include "chan.h"
24 #include "modules.h"
25 #include "tandem.h"
26 char natip[121] = "";
27
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 char spaces[33] = " ";
31 char spaces2[33] = " ";
32
33 extern struct dcc_t *dcc;
34 extern int dcc_total;
35 extern int noshare;
36 extern struct userrec *userlist, *lastuser;
37 extern struct banrec *global_bans;
38 extern struct igrec *global_ign;
39 extern char botnetnick[];
40 extern struct chanset_t *chanset;
41 extern Tcl_Interp *interp;
42 extern time_t now;
43 extern int use_silence;
44
45 char userfile[121] = ""; /* where the user records are stored */
46 int ignore_time = 10; /* how many minutes will ignores last? */
47 int gban_total = 0; /* Total number of global bans */
48
49 /* is this nick!user@host being ignored? */
50 int match_ignore(char *uhost)
51 {
52 struct igrec *ir;
53
54 for (ir = global_ign; ir; ir = ir->next)
55 if (wild_match(ir->igmask, uhost))
56 return 1;
57 return 0;
58 }
59
60 int equals_ignore(char *uhost)
61 {
62 struct igrec *u = global_ign;
63
64 for (; u; u = u->next)
65 if (!rfc_casecmp(u->igmask, uhost)) {
66 if (u->flags & IGREC_PERM)
67 return 2;
68 else
69 return 1;
70 }
71 return 0;
72 }
73
74 int delignore(char *ign)
75 {
76 int i, j;
77 struct igrec **u;
78 struct igrec *t;
79
80 context;
81
82 i = 0;
83 if (!strchr(ign, '!') && (j = atoi(ign))) {
84 for (u = &global_ign, j--; *u && j; u = &((*u)->next), j--);
85 if (*u) {
86 strcpy(ign, (*u)->igmask);
87 i = 1;
88 }
89 } else {
90 /* find the matching host, if there is one */
91 for (u = &global_ign; *u && !i; u = &((*u)->next))
92 if (!rfc_casecmp(ign, (*u)->igmask)) {
93 i = 1;
94 break;
95 }
96 }
97 if (i) {
98 if (!noshare)
99 shareout(NULL, "-i %s\n", ign);
100 nfree((*u)->igmask);
101 if ((*u)->msg)
102 nfree((*u)->msg);
103 if ((*u)->user)
104 nfree((*u)->user);
105 t = *u;
106 *u = (*u)->next;
107 nfree(t);
108 }
109 return i;
110 }
111
112 void addignore(char *ign, char *from, char *mnote, time_t expire_time)
113 {
114 struct igrec *p;
115
116 if (equals_ignore(ign))
117 delignore(ign); /* remove old ignore */
118 p = user_malloc(sizeof(struct igrec));
119
120 p->next = global_ign;
121 global_ign = p;
122 p->expire = expire_time;
123 p->added = now;
124 p->flags = expire_time ? 0 : IGREC_PERM;
125 p->igmask = user_malloc(strlen(ign) + 1);
126 strcpy(p->igmask, ign);
127 p->user = user_malloc(strlen(from) + 1);
128 strcpy(p->user, from);
129 p->msg = user_malloc(strlen(mnote) + 1);
130 strcpy(p->msg, mnote);
131 if (!noshare)
132 shareout(NULL, "+i %s %lu %c %s %s\n", ign, expire_time - now,
133 (p->flags & IGREC_PERM) ? 'p' : '-', from, mnote);
134 }
135
136 /* take host entry from ignore list and display it ignore-style */
137 void display_ignore(int idx, int number, struct igrec *ignore)
138 {
139 char dates[81], s[41];
140
141 if (ignore->added) {
142 daysago(now, ignore->added, s);
143 sprintf(dates, "Started %s", s);
144 } else
145 dates[0] = 0;
146 if (ignore->flags & IGREC_PERM)
147 strcpy(s, "(perm)");
148 else {
149 char s1[41];
150
151 days(ignore->expire, now, s1);
152 sprintf(s, "(expires %s)", s1);
153 }
154 if (number >= 0)
155 dprintf(idx, " [%3d] %s %s\n", number, ignore->igmask, s);
156 else
157 dprintf(idx, "IGNORE: %s %s\n", ignore->igmask, s);
158 if (ignore->msg && ignore->msg[0])
159 dprintf(idx, " %s: %s\n", ignore->user, ignore->msg);
160 else
161 dprintf(idx, " %s %s\n", BANS_PLACEDBY, ignore->user);
162 if (dates[0])
163 dprintf(idx, " %s\n", dates);
164 }
165
166 /* list the ignores and how long they've been active */
167 void tell_ignores(int idx, char *match)
168 {
169 struct igrec *u = global_ign;
170 int k = 1;
171
172 if (u == NULL) {
173 dprintf(idx, "No ignores.\n");
174 return;
175 }
176 dprintf(idx, "%s:\n", IGN_CURRENT);
177 for (; u; u = u->next) {
178 if (match[0]) {
179 if (wild_match(match, u->igmask) ||
180 wild_match(match, u->msg) ||
181 wild_match(match, u->user))
182 display_ignore(idx, k, u);
183 k++;
184 } else
185 display_ignore(idx, k++, u);
186 }
187 }
188
189 /* check for expired timed-ignores */
190 void check_expired_ignores()
191 {
192 struct igrec **u = &global_ign;
193
194 if (!*u)
195 return;
196 while (*u) {
197 if (!((*u)->flags & IGREC_PERM) && (now >= (*u)->expire)) {
198 putlog(LOG_MISC, "*", "%s %s (%s)", IGN_NOLONGER, (*u)->igmask,
199 MISC_EXPIRED);
200 if (use_silence) {
201 char *p;
202
203 /* possibly an ircu silence was added for this user */
204 p = strchr((*u)->igmask, '!');
205 if (p == NULL)
206 p = (*u)->igmask;
207 else
208 p++;
209 dprintf(DP_SERVER, "SILENCE -%s\n", p);
210 }
211 delignore((*u)->igmask);
212 } else {
213 u = &((*u)->next);
214 }
215 }
216 }
217
218 /* channel ban loaded from user file */
219 static void addban_fully(struct chanset_t *chan, char *ban, char *from,
220 char *note, time_t expire_time, int flags,
221 time_t added, time_t last)
222 {
223 struct banrec *p = user_malloc(sizeof(struct banrec));
224 struct banrec **u = chan ? &chan->bans : &global_bans;
225 char *t;
226
227 /* decode gibberish stuff */
228 t = strchr(note, '~');
229 while (t != NULL) {
230 *t = ' ';
231 t = strchr(note, '~');
232 }
233 t = strchr(note, '`');
234 while (t != NULL) {
235 *t = ',';
236 t = strchr(note, '`');
237 }
238 p->next = *u;
239 *u = p;
240 p->expire = expire_time;
241 p->added = added;
242 p->lastactive = last;
243 p->flags = flags;
244 p->banmask = user_malloc(strlen(ban) + 1);
245 strcpy(p->banmask, ban);
246 p->user = user_malloc(strlen(from) + 1);
247 strcpy(p->user, from);
248 p->desc = user_malloc(strlen(note) + 1);
249 strcpy(p->desc, note);
250 }
251
252 static void restore_chanban(struct chanset_t *chan, char *host)
253 {
254 char *expi, *add, *last, *user, *desc;
255 int flags = 0;
256
257 expi = strchr(host, ':');
258 if (expi) {
259 *expi = 0;
260 expi++;
261 if (*expi == '+') {
262 flags |= BANREC_PERM;
263 expi++;
264 }
265 add = strchr(expi, ':');
266 if (add) {
267 if (add[-1] == '*') {
268 flags |= BANREC_STICKY;
269 add[-1] = 0;
270 } else
271 *add = 0;
272 add++;
273 if (*add == '+') {
274 last = strchr(add, ':');
275 if (last) {
276 *last = 0;
277 last++;
278 user = strchr(last, ':');
279 if (user) {
280 *user = 0;
281 user++;
282 desc = strchr(user, ':');
283 if (desc) {
284 *desc = 0;
285 desc++;
286 addban_fully(chan, host, user, desc, atoi(expi), flags,
287 atoi(add), atoi(last));
288 return;
289 }
290 }
291 }
292 } else {
293 desc = strchr(add, ':');
294 if (desc) {
295 *desc = 0;
296 desc++;
297 addban_fully(chan, host, add, desc, atoi(expi), flags, now, 0);
298 return;
299 }
300 }
301 }
302 }
303 putlog(LOG_MISC, "*", "*** Malformed banline for %s.\n",
304 chan ? chan->name : "global_bans");
305 }
306
307 static void restore_ignore(char *host)
308 {
309 char *expi, *user, *added, *desc, *t;
310 int flags = 0;
311 struct igrec *p;
312
313 expi = strchr(host, ':');
314 if (expi) {
315 *expi = 0;
316 expi++;
317 if (*expi == '+') {
318 flags |= IGREC_PERM;
319 expi++;
320 }
321 user = strchr(expi, ':');
322 if (user) {
323 *user = 0;
324 user++;
325 added = strchr(user, ':');
326 if (added) {
327 *added = 0;
328 added++;
329 desc = strchr(added, ':');
330 if (desc) {
331 *desc = 0;
332 desc++;
333 /* decode gibberish stuff */
334 t = strchr(desc, '~');
335 while (t != NULL) {
336 *t = ' ';
337 t = strchr(desc, '~');
338 }
339 t = strchr(desc, '`');
340 while (t != NULL) {
341 *t = ',';
342 t = strchr(desc, '`');
343 }
344 } else
345 desc = NULL;
346 } else {
347 added = "0";
348 desc = NULL;
349 }
350 p = user_malloc(sizeof(struct igrec));
351
352 p->next = global_ign;
353 global_ign = p;
354 p->expire = atoi(expi);
355 p->added = atoi(added);
356 p->flags = flags;
357 p->igmask = user_malloc(strlen(host) + 1);
358 strcpy(p->igmask, host);
359 p->user = user_malloc(strlen(user) + 1);
360 strcpy(p->user, user);
361 if (desc) {
362 p->msg = user_malloc(strlen(desc) + 1);
363 strcpy(p->msg, desc);
364 } else
365 p->msg = NULL;
366 return;
367 }
368 }
369 putlog(LOG_MISC, "*", "*** Malformed ignore line.\n");
370 }
371
372 void tell_user(int idx, struct userrec *u, int master)
373 {
374 char s[81], s1[81];
375 int n, l = HANDLEN - strlen(u->handle);
376 time_t now2;
377 struct chanuserrec *ch;
378 struct user_entry *ue;
379 struct laston_info *li;
380 struct flag_record fr =
381 {FR_GLOBAL, 0, 0, 0, 0, 0};
382
383 context;
384 fr.global = u->flags;
385
386 fr.udef_global = u->flags_udef;
387 build_flags(s, &fr, NULL);
388 Tcl_SetVar(interp, "user", u->handle, 0);
389 n = 0;
390 if (Tcl_VarEval(interp, "notes ", "$user", NULL) == TCL_OK)
391 n = atoi(interp->result);
392 li = get_user(&USERENTRY_LASTON, u);
393 if (!li || !li->laston)
394 strcpy(s1, "never");
395 else {
396 now2 = now - li->laston;
397 strcpy(s1, ctime(&li->laston));
398 if (now2 > 86400) {
399 s1[7] = 0;
400 strcpy(&s1[11], &s1[4]);
401 strcpy(s1, &s1[8]);
402 } else {
403 s1[16] = 0;
404 strcpy(s1, &s1[11]);
405 }
406 }
407 context;
408 spaces[l] = 0;
409 dprintf(idx, "%s%s %-5s%5d %-15s %s (%-10.10s)\n", u->handle, spaces,
410 get_user(&USERENTRY_PASS, u) ? "yes" : "no", n, s, s1,
411 (li && li->lastonplace) ? li->lastonplace : "nowhere");
412 spaces[l] = ' ';
413 /* channel flags? */
414 context;
415 ch = u->chanrec;
416 while (ch != NULL) {
417 fr.match = FR_CHAN | FR_GLOBAL;
418 get_user_flagrec(dcc[idx].user, &fr, ch->channel);
419 if (glob_op(fr) || chan_op(fr)) {
420 if (ch->laston == 0L)
421 strcpy(s1, "never");
422 else {
423 now2 = now - (ch->laston);
424 strcpy(s1, ctime(&(ch->laston)));
425 if (now2 > 86400) {
426 s1[7] = 0;
427 strcpy(&s1[11], &s1[4]);
428 strcpy(s1, &s1[8]);
429 } else {
430 s1[16] = 0;
431 strcpy(s1, &s1[11]);
432 }
433 }
434 fr.match = FR_CHAN;
435 fr.chan = ch->flags;
436 fr.udef_chan = ch->flags_udef;
437 build_flags(s, &fr, NULL);
438 spaces[HANDLEN - 9] = 0;
439 dprintf(idx, "%s %-18s %-15s %s\n", spaces, ch->channel, s, s1);
440 spaces[HANDLEN - 9] = ' ';
441 if (ch->info != NULL)
442 dprintf(idx, " INFO: %s\n", ch->info);
443 }
444 ch = ch->next;
445 }
446 /* user-defined extra fields */
447 context;
448 for (ue = u->entries; ue; ue = ue->next)
449 if (!ue->name && ue->type->display)
450 ue->type->display(idx, ue);
451 }
452
453 /* show user by ident */
454 void tell_user_ident(int idx, char *id, int master)
455 {
456 struct userrec *u;
457
458 u = get_user_by_handle(userlist, id);
459 if (u == NULL)
460 u = get_user_by_host(id);
461 if (u == NULL) {
462 dprintf(idx, "%s.\n", USERF_NOMATCH);
463 return;
464 }
465 spaces[HANDLEN - 6] = 0;
466 dprintf(idx, "HANDLE%s PASS NOTES FLAGS LAST\n", spaces);
467 spaces[HANDLEN - 6] = ' ';
468 tell_user(idx, u, master);
469 }
470
471 /* match string:
472 * wildcard to match nickname or hostmasks
473 * +attr to find all with attr */
474 void tell_users_match(int idx, char *mtch, int start, int limit,
475 int master, char *chname)
476 {
477 struct userrec *u = userlist;
478 int fnd = 0, cnt, nomns = 0, flags = 0;
479 struct list_type *q;
480 struct flag_record user, pls, mns;
481
482 context;
483 dprintf(idx, "*** %s '%s':\n", MISC_MATCHING, mtch);
484 cnt = 0;
485 spaces[HANDLEN - 6] = 0;
486 dprintf(idx, "HANDLE%s PASS NOTES FLAGS LAST\n", spaces);
487 spaces[HANDLEN - 6] = ' ';
488 if (start > 1)
489 dprintf(idx, "(%s %d)\n", MISC_SKIPPING, start - 1);
490 if (strchr("+-&|", *mtch)) {
491 user.match = pls.match = FR_GLOBAL | FR_BOT | FR_CHAN;
492 break_down_flags(mtch, &pls, &mns);
493 mns.match = pls.match ^ (FR_AND | FR_OR);
494 if (!mns.global && !mns.udef_global && !mns.chan && !mns.udef_chan &&
495 !mns.bot) {
496 nomns = 1;
497 if (!pls.global && !pls.udef_global && !pls.chan && !pls.udef_chan &&
498 !pls.bot) {
499 /* happy now BB you weenie :P */
500 dprintf(idx, "Unknown flag specified for matching!!\n");
501 return;
502 }
503 }
504 if (!chname || !chname[0])
505 chname = dcc[idx].u.chat->con_chan;
506 flags = 1;
507 }
508 while (u != NULL) {
509 if (flags) {
510 get_user_flagrec(u, &user, chname);
511 if (flagrec_eq(&pls, &user)) {
512 if (nomns || !flagrec_eq(&mns, &user)) {
513 cnt++;
514 if ((cnt <= limit) && (cnt >= start))
515 tell_user(idx, u, master);
516 if (cnt == limit + 1)
517 dprintf(idx, MISC_TRUNCATED, limit);
518 }
519 }
520 } else if (wild_match(mtch, u->handle)) {
521 cnt++;
522 if ((cnt <= limit) && (cnt >= start))
523 tell_user(idx, u, master);
524 if (cnt == limit + 1)
525 dprintf(idx, MISC_TRUNCATED, limit);
526 } else {
527 fnd = 0;
528 for (q = get_user(&USERENTRY_HOSTS, u); q; q = q->next) {
529 if ((wild_match(mtch, q->extra)) && (!fnd)) {
530 cnt++;
531 fnd = 1;
532 if ((cnt <= limit) && (cnt >= start)) {
533 tell_user(idx, u, master);
534 }
535 if (cnt == limit + 1)
536 dprintf(idx, MISC_TRUNCATED, limit);
537 }
538 }
539 }
540 u = u->next;
541 }
542 dprintf(idx, MISC_FOUNDMATCH, cnt, cnt == 1 ? "" : "es");
543 }
544
545 /*
546 * tagged lines in the user file:
547 * * OLD:
548 * # (comment)
549 * ; (comment)
550 * - hostmask(s)
551 * + email
552 * * dcc directory
553 * = comment
554 * : info line
555 * . xtra (Tcl)
556 * ! channel-specific
557 * !! global laston
558 * :: channel-specific bans
559 * NEW:
560 * *ban global bans
561 * *ignore global ignores
562 * ::#chan channel bans
563 * - entries in each
564 * <handle> begin user entry
565 * --KEY INFO - info on each
566 */
567
568 int noxtra = 0;
569 int readuserfile(char *file, struct userrec **ret)
570 {
571 char *p, buf[512], lasthand[512], *attr, *pass, *code, s1[512], *s;
572 FILE *f;
573 struct userrec *bu, *u = NULL;
574 struct chanset_t *cst = NULL;
575 int i;
576 char ignored[512];
577 struct flag_record fr;
578 struct chanuserrec *cr;
579
580 context;
581 bu = (*ret);
582 ignored[0] = 0;
583 if (bu == userlist) {
584 clear_chanlist();
585 lastuser = NULL;
586 global_bans = NULL;
587 global_ign = NULL;
588 }
589 lasthand[0] = 0;
590 f = fopen(file, "r");
591 if (f == NULL)
592 return 0;
593 noshare = noxtra = 1;
594 context;
595 /* read opening comment */
596 s = buf;
597 fgets(s, 180, f);
598 if (s[1] < '4') {
599 fatal(USERF_OLDFMT, 0);
600 }
601 if (s[1] > '4')
602 fatal(USERF_INVALID, 0);
603 gban_total = 0;
604 while (!feof(f)) {
605 s = buf;
606 fgets(s, 511, f);
607 if (!feof(f)) {
608 if ((s[0] != '#') && (s[0] != ';') && (s[0])) {
609 code = newsplit(&s);
610 rmspace(s);
611 if (!strcmp(code, "-")) {
612 if (lasthand[0]) {
613 if (u) { /* only break it down if there a real users */
614 p = strchr(s, ',');
615 while (p != NULL) {
616 splitc(s1, s, ',');
617 rmspace(s1);
618 if (s1[0])
619 set_user(&USERENTRY_HOSTS, u, s1);
620 p = strchr(s, ',');
621 }
622 }
623 /* channel bans are never stacked with , */
624 if (s[0]) {
625 if (strchr(CHANMETA, lasthand[0]) != NULL)
626 restore_chanban(cst, s);
627 else if (lasthand[0] == '*') {
628 if (lasthand[1] == 'i') {
629 restore_ignore(s);
630 } else {
631 restore_chanban(NULL, s);
632 gban_total++;
633 }
634 } else if (lasthand[0]) {
635 set_user(&USERENTRY_HOSTS, u, s);
636 }
637 }
638 }
639 } else if (!strcmp(code, "!")) {
640 /* ! #chan laston flags [info] */
641 char *chname, *st, *fl;
642
643 if (u) {
644 chname = newsplit(&s);
645 st = newsplit(&s);
646 fl = newsplit(&s);
647 rmspace(s);
648 fr.match = FR_CHAN;
649 break_down_flags(fl, &fr, 0);
650 if (findchan(chname)) {
651 for (cr = u->chanrec; cr; cr = cr->next)
652 if (!rfc_casecmp(cr->channel, chname))
653 break;
654 if (!cr) {
655 cr = (struct chanuserrec *)
656 user_malloc(sizeof(struct chanuserrec));
657
658 cr->next = u->chanrec;
659 u->chanrec = cr;
660 strncpy(cr->channel, chname, 80);
661 cr->channel[80] = 0;
662 cr->laston = atoi(st);
663 cr->flags = fr.chan;
664 cr->flags_udef = fr.udef_chan;
665 if (s[0]) {
666 cr->info = (char *) nmalloc(strlen(s) + 1);
667 strcpy(cr->info, s);
668 } else
669 cr->info = NULL;
670 }
671 }
672 }
673 } else if (!strncmp(code, "::", 2)) {
674 /* channel-specific bans */
675 strcpy(lasthand, &code[2]);
676 if (!findchan(lasthand)) {
677 strcat(ignored, lasthand);
678 strcat(ignored, " ");
679 lasthand[0] = 0;
680 u = 0;
681 } else {
682 /* Remove all bans for this channel to avoid dupes */
683 /* NOTE only remove bans for when getting a userfile
684 * from another bot & that channel is shared */
685 cst = findchan(lasthand);
686 if ((*ret == userlist) || channel_shared(cst)) {
687 while (cst->bans) {
688 struct banrec *b = cst->bans;
689
690 cst->bans = b->next;
691 if (b->banmask)
692 nfree(b->banmask);
693 if (b->user)
694 nfree(b->user);
695 if (b->desc)
696 nfree(b->desc);
697 nfree(b);
698 }
699 } else {
700 /* otherwise ignore any bans for this channel */
701 cst = NULL;
702 lasthand[0] = 0;
703 }
704 }
705 } else if (!strncmp(code, "--", 2)) {
706 /* new format storage */
707 struct user_entry *ue;
708 int ok = 0;
709
710 context;
711 if (u) {
712 ue = u->entries;
713 for (; ue && !ok; ue = ue->next)
714 if (ue->name && !strcasecmp(code + 2, ue->name)) {
715 struct list_type *list;
716
717 list = user_malloc(sizeof(struct list_type));
718
719 list->next = NULL;
720 list->extra = user_malloc(strlen(s) + 1);
721 strcpy(list->extra, s);
722 list_append((&ue->u.list), list);
723 ok = 1;
724 }
725 if (!ok) {
726 ue = user_malloc(sizeof(struct user_entry));
727
728 ue->name = user_malloc(strlen(code + 1));
729 ue->type = NULL;
730 strcpy(ue->name, code + 2);
731 ue->u.list = user_malloc(sizeof(struct list_type));
732
733 ue->u.list->next = NULL;
734 ue->u.list->extra = user_malloc(strlen(s) + 1);
735 strcpy(ue->u.list->extra, s);
736 list_insert((&u->entries), ue);
737 }
738 }
739 } else if (!rfc_casecmp(code, BAN_NAME)) {
740 strcpy(lasthand, code);
741 u = NULL;
742 } else if (!rfc_casecmp(code, IGNORE_NAME)) {
743 strcpy(lasthand, code);
744 u = NULL;
745 } else if (!rfc_casecmp(code, EXEMPT_NAME)) {
746 strcpy(lasthand, code);
747 u = NULL;
748 } else if (!rfc_casecmp(code, INVITE_NAME)) {
749 strcpy(lasthand, code);
750 u = NULL;
751 } else if (code[0] == '*') {
752 lasthand[0] = 0;
753 u = NULL;
754 } else {
755 pass = newsplit(&s);
756 attr = newsplit(&s);
757 rmspace(s);
758 if (!attr[0] || !pass[0]) {
759 putlog(LOG_MISC, "*", "* %s '%s'!", USERF_CORRUPT, code);
760 lasthand[0] = 0;
761 } else {
762 u = get_user_by_handle(bu, code);
763 if (u && !(u->flags & USER_UNSHARED)) {
764 putlog(LOG_MISC, "*", "* %s '%s'!", USERF_DUPE, code);
765 lasthand[0] = 0;
766 u = NULL;
767 } else if (u) {
768 lasthand[0] = 0;
769 u = NULL;
770 } else {
771 fr.match = FR_GLOBAL;
772 break_down_flags(attr, &fr, 0);
773 strcpy(lasthand, code);
774 cst = NULL;
775 if (strlen(code) > HANDLEN)
776 code[HANDLEN] = 0;
777 if (strlen(pass) > 20) {
778 putlog(LOG_MISC, "*", "* %s '%s'", USERF_BROKEPASS, code);
779 strcpy(pass, "-");
780 }
781 bu = adduser(bu, code, 0, pass,
782 sanity_check(fr.global &USER_VALID));
783
784 u = get_user_by_handle(bu, code);
785 for (i = 0; i < dcc_total; i++)
786 if (!strcasecmp(code, dcc[i].nick))
787 dcc[i].user = u;
788 u->flags_udef = fr.udef_global;
789 /* if s starts with '/' it's got file info */
790 }
791 }
792 }
793 }
794 }
795 }
796 context;
797 fclose(f);
798 (*ret) = bu;
799 if (ignored[0]) {
800 putlog(LOG_MISC, "*", "%s %s", USERF_IGNBANS, ignored);
801 }
802 putlog(LOG_MISC, "*", "Userfile loaded, unpacking...");
803 context;
804 for (u = bu; u; u = u->next) {
805 struct user_entry *e;
806
807 for (e = u->entries; e; e = e->next)
808 if (e->name) {
809 struct user_entry_type *uet = find_entry_type(e->name);
810
811 if (uet) {
812 e->type = uet;
813 uet->unpack(u, e);
814 nfree(e->name);
815 e->name = NULL;
816 }
817 }
818 }
819 noshare = noxtra = 0;
820 context;
821 /* process the user data *now* */
822 return 1;
823 }
824
825 /* New methodology - cycle through list 3 times
826 * 1st time scan for +sh bots and link if none connected
827 * 2nd time scan for +h bots
828 * 3rd time scan for +a/+h bots */
829 void autolink_cycle(char *start)
830 {
831 struct userrec *u = userlist, *autc = NULL;
832 static int cycle = 0;
833 int got_hub = 0, got_alt = 0, got_shared = 0, linked, ready = 0, i,
834 bfl;
835
836 context;
837 /* don't start a new cycle if some links are still pending */
838 if (!start) {
839 for (i = 0; i < dcc_total; i++) {
840 if (dcc[i].type == &DCC_BOT_NEW)
841 return;
842 if (dcc[i].type == &DCC_FORK_BOT)
843 return;
844 }
845 }
846 if (!start) {
847 ready = 1;
848 cycle = 0;
849 } /* new run through the user list */
850 while (u && !autc) {
851 while (u && !autc) {
852 if (u->flags & USER_BOT) {
853 bfl = bot_flags(u);
854 if (bfl & (BOT_HUB | BOT_ALT)) {
855 linked = 0;
856 for (i = 0; i < dcc_total; i++) {
857 if (dcc[i].user == u) {
858 if (dcc[i].type == &DCC_BOT)
859 linked = 1;
860 if (dcc[i].type == &DCC_BOT_NEW)
861 linked = 1;
862 if (dcc[i].type == &DCC_FORK_BOT)
863 linked = 1;
864 }
865 }
866 if ((bfl & BOT_HUB) && (bfl & BOT_SHARE)) {
867 if (linked)
868 got_shared = 1;
869 else if ((cycle == 0) && ready && !autc)
870 autc = u;
871 } else if ((bfl & BOT_HUB) && cycle > 0) {
872 if (linked)
873 got_hub = 1;
874 else if ((cycle == 1) && ready && !autc)
875 autc = u;
876 } else if ((bfl & BOT_ALT) && (cycle == 2)) {
877 if (linked)
878 got_alt = 1;
879 else if (!in_chain(u->handle) && ready && !autc)
880 autc = u;
881 }
882 /* did we make it where we're supposed to start? yay! */
883 if (!ready)
884 if (!strcasecmp(u->handle, start)) {
885 ready = 1;
886 autc = NULL;
887 /* if starting point is a +h bot, must be in 2nd cycle */
888 if ((bfl & BOT_HUB) && !(bfl & BOT_SHARE)) {
889 cycle = 1;
890 }
891 /* if starting point is a +a bot, must be in 3rd cycle */
892 if (bfl & BOT_ALT) {
893 cycle = 2;
894 }
895 }
896 }
897 if ((cycle == 0) && (bfl & BOT_REJECT) && in_chain(u->handle)) {
898 /* get rid of nasty reject bot */
899 int i;
900
901 i = nextbot(u->handle);
902 if ((i >= 0) && !strcasecmp(dcc[i].nick, u->handle)) {
903 char *p = MISC_REJECTED;
904
905 /* we're directly connected to the offending bot?! (shudder!) */
906 putlog(LOG_BOTS, "*", "%s %s", BOT_REJECTING, dcc[i].nick);
907 chatout("*** %s bot %s\n", p, dcc[i].nick);
908 botnet_send_unlinked(i, dcc[i].nick, p);
909 dprintf(i, "bye\n");
910 killsock(dcc[i].sock);
911 lostdcc(i);
912 } else {
913 botnet_send_reject(i, botnetnick, NULL, u->handle, NULL, NULL);
914 }
915 }
916 }
917 u = u->next;
918 }
919 if (!autc) {
920 if ((cycle == 0) && !got_shared) {
921 cycle++;
922 u = userlist;
923 } else if ((cycle == 1) && !(got_shared || got_hub)) {
924 cycle++;
925 u = userlist;
926 }
927 }
928 }
929 if (got_shared && (cycle == 0))
930 autc = NULL;
931 else if ((got_shared || got_hub) && (cycle == 1))
932 autc = NULL;
933 else if ((got_shared || got_hub || got_alt) && (cycle == 2))
934 autc = NULL;
935 if (autc)
936 botlink("", -3, autc->handle); /* try autoconnect */
937 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23