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

Contents of /eggdrop1.9/src/users.c

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


Revision 1.54 - (show annotations) (download) (as text)
Sun May 11 02:40:28 2003 UTC (16 years, 5 months ago) by stdarg
Branch: MAIN
CVS Tags: HEAD
Changes since 1.53: +1 -1 lines
File MIME type: text/x-chdr
FILE REMOVED
* Remove some stray files

1 /*
2 * users.c --
3 *
4 * testing and enforcing ignores
5 * adding and removing ignores
6 * listing ignores
7 * auto-linking bots
8 * sending and receiving a userfile from a bot
9 * listing users ('.whois' and '.match')
10 * reading the user file
11 *
12 * dprintf'ized, 9nov1995
13 */
14 /*
15 * Copyright (C) 1997 Robey Pointer
16 * Copyright (C) 1999, 2000, 2001, 2002, 2003 Eggheads Development Team
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 */
32
33 #ifndef lint
34 static const char rcsid[] = "$Id: users.c,v 1.53 2003/03/06 12:08:15 tothwolf Exp $";
35 #endif
36
37 #include "main.h"
38 #include "users.h"
39 #include "chan.h"
40 #include "modules.h"
41 #include "logfile.h"
42 #include "misc.h"
43 #include "chanprog.h" /* clear_chanlist */
44 #include "dccutil.h" /* dprintf_eggdrop, chatout, lostdcc */
45 #include "net.h" /* killsock */
46 #include "userrec.h" /* clear_masks */
47 #include "users.h" /* prototypes */
48
49 char natip[121] = "";
50
51 #include <netinet/in.h>
52 #include <arpa/inet.h>
53 char spaces[33] = " ";
54 char spaces2[33] = " ";
55
56 extern struct dcc_t *dcc;
57 extern struct userrec *userlist, *lastuser;
58 extern struct chanset_t *chanset;
59 extern int dcc_total;
60 extern char myname[];
61 extern time_t now;
62 extern int userfile_perm;
63
64 #ifndef MAKING_MODS
65 extern struct dcc_table DCC_BOT, DCC_BOT_NEW, DCC_FORK_BOT, DCC_DNSWAIT;
66 #endif /* MAKING_MODS */
67
68 char userfile[121] = ""; /* where the user records are stored */
69 int ignore_time = 10; /* how many minutes will ignores last? */
70
71 static script_linked_var_t user_script_vars[] = {
72 {"", "userfile_perm", &userfile_perm, SCRIPT_INTEGER, NULL},
73 {0}
74 };
75
76 int old_user_init()
77 {
78 script_link_vars(user_script_vars);
79 return(0);
80 }
81
82 /* is this nick!user@host being ignored? */
83 int match_ignore(char *uhost)
84 {
85 struct igrec *ir;
86
87 for (ir = global_ign; ir; ir = ir->next)
88 if (wild_match(ir->igmask, uhost))
89 return 1;
90 return 0;
91 }
92
93 int equals_ignore(char *uhost)
94 {
95 struct igrec *u = global_ign;
96
97 for (; u; u = u->next)
98 if (!irccmp(u->igmask, uhost)) {
99 if (u->flags & IGREC_PERM)
100 return 2;
101 else
102 return 1;
103 }
104 return 0;
105 }
106
107 int delignore(char *ign)
108 {
109 int i, j;
110 struct igrec **u;
111 struct igrec *t;
112 char temp[256];
113
114 i = 0;
115 if (!strchr(ign, '!') && (j = atoi(ign))) {
116 for (u = &global_ign, j--; *u && j; u = &((*u)->next), j--);
117 if (*u) {
118 strlcpy(temp, (*u)->igmask, sizeof temp);
119 i = 1;
120 }
121 } else {
122 /* find the matching host, if there is one */
123 for (u = &global_ign; *u && !i; u = &((*u)->next))
124 if (!irccmp(ign, (*u)->igmask)) {
125 strlcpy(temp, ign, sizeof temp);
126 i = 1;
127 break;
128 }
129 }
130 if (i) {
131 free((*u)->igmask);
132 if ((*u)->msg)
133 free((*u)->msg);
134 if ((*u)->user)
135 free((*u)->user);
136 t = *u;
137 *u = (*u)->next;
138 free(t);
139 }
140 return i;
141 }
142
143 void addignore(char *ign, char *from, char *mnote, time_t expire_time)
144 {
145 struct igrec *p;
146
147 if (equals_ignore(ign))
148 delignore(ign); /* remove old ignore */
149 p = malloc(sizeof(struct igrec));
150
151 p->next = global_ign;
152 global_ign = p;
153 p->expire = expire_time;
154 p->added = now;
155 p->flags = expire_time ? 0 : IGREC_PERM;
156 p->igmask = strdup(ign);
157 p->user = strdup(from);
158 p->msg = strdup(mnote);
159 }
160
161 /* take host entry from ignore list and display it ignore-style */
162 void display_ignore(int idx, int number, struct igrec *ignore)
163 {
164 char dates[81], s[41];
165
166 if (ignore->added) {
167 daysago(now, ignore->added, s);
168 sprintf(dates, "Started %s", s);
169 } else
170 dates[0] = 0;
171 if (ignore->flags & IGREC_PERM)
172 strcpy(s, "(perm)");
173 else {
174 char s1[41];
175
176 days(ignore->expire, now, s1);
177 sprintf(s, "(expires %s)", s1);
178 }
179 if (number >= 0)
180 dprintf(idx, " [%3d] %s %s\n", number, ignore->igmask, s);
181 else
182 dprintf(idx, "IGNORE: %s %s\n", ignore->igmask, s);
183 if (ignore->msg && ignore->msg[0])
184 dprintf(idx, " %s: %s\n", ignore->user, ignore->msg);
185 else
186 dprintf(idx, " %s %s\n", _("placed by"), ignore->user);
187 if (dates[0])
188 dprintf(idx, " %s\n", dates);
189 }
190
191 /* list the ignores and how long they've been active */
192 void tell_ignores(int idx, char *match)
193 {
194 struct igrec *u = global_ign;
195 int k = 1;
196
197 if (u == NULL) {
198 dprintf(idx, "No ignores.\n");
199 return;
200 }
201 dprintf(idx, "%s:\n", _("Currently ignoring"));
202 for (; u; u = u->next) {
203 if (match[0]) {
204 if (wild_match(match, u->igmask) ||
205 wild_match(match, u->msg) ||
206 wild_match(match, u->user))
207 display_ignore(idx, k, u);
208 k++;
209 } else
210 display_ignore(idx, k++, u);
211 }
212 }
213
214 /* check for expired timed-ignores */
215 void check_expired_ignores()
216 {
217 struct igrec **u = &global_ign;
218
219 if (!*u)
220 return;
221 while (*u) {
222 if (!((*u)->flags & IGREC_PERM) && (now >= (*u)->expire)) {
223 putlog(LOG_MISC, "*", "%s %s (%s)", _("No longer ignoring"), (*u)->igmask,
224 _("expired"));
225 delignore((*u)->igmask);
226 } else {
227 u = &((*u)->next);
228 }
229 }
230 }
231
232 /* Channel mask loaded from user file. This function is
233 * add(ban|invite|exempt)_fully merged into one. <cybah>
234 */
235 static void addmask_fully(struct chanset_t *chan, maskrec **m, maskrec **global,
236 char *mask, char *from,
237 char *note, time_t expire_time, int flags,
238 time_t added, time_t last)
239 {
240 maskrec *p = malloc(sizeof(maskrec));
241 maskrec **u = (chan) ? m : global;
242
243 p->next = *u;
244 *u = p;
245 p->expire = expire_time;
246 p->added = added;
247 p->lastactive = last;
248 p->flags = flags;
249 p->mask = strdup(mask);
250 p->user = strdup(from);
251 p->desc = strdup(note);
252 }
253
254 static void restore_chanban(struct chanset_t *chan, char *host)
255 {
256 char *expi, *add, *last, *user, *desc;
257 int flags = 0;
258
259 expi = strchr_unescape(host, ':', '\\');
260 if (expi) {
261 if (*expi == '+') {
262 flags |= MASKREC_PERM;
263 expi++;
264 }
265 add = strchr(expi, ':');
266 if (add) {
267 if (add[-1] == '*') {
268 flags |= MASKREC_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 addmask_fully(chan, &chan->bans, &global_bans, host, user,
287 desc, atoi(expi), flags, atoi(add), atoi(last));
288 return;
289 }
290 }
291 }
292 } else {
293 desc = strchr(add, ':');
294 if (desc) {
295 *desc = 0;
296 desc++;
297 addmask_fully(chan, &chan->bans, &global_bans, host, add, desc,
298 atoi(expi), flags, now, 0);
299 return;
300 }
301 }
302 }
303 }
304 putlog(LOG_MISC, "*", "*** Malformed banline for %s.",
305 chan ? chan->dname : "global_bans");
306 }
307
308 static void restore_chanexempt(struct chanset_t *chan, char *host)
309 {
310 char *expi, *add, *last, *user, *desc;
311 int flags = 0;
312
313 expi = strchr_unescape(host, ':', '\\');
314 if (expi) {
315 if (*expi == '+') {
316 flags |= MASKREC_PERM;
317 expi++;
318 }
319 add = strchr(expi, ':');
320 if (add) {
321 if (add[-1] == '*') {
322 flags |= MASKREC_STICKY;
323 add[-1] = 0;
324 } else
325 *add = 0;
326 add++;
327 if (*add == '+') {
328 last = strchr(add, ':');
329 if (last) {
330 *last = 0;
331 last++;
332 user = strchr(last, ':');
333 if (user) {
334 *user = 0;
335 user++;
336 desc = strchr(user, ':');
337 if (desc) {
338 *desc = 0;
339 desc++;
340 addmask_fully(chan, &chan->exempts, &global_exempts, host, user,
341 desc, atoi(expi), flags, atoi(add), atoi(last));
342 return;
343 }
344 }
345 }
346 } else {
347 desc = strchr(add, ':');
348 if (desc) {
349 *desc = 0;
350 desc++;
351 addmask_fully(chan, &chan->exempts, &global_exempts, host, add,
352 desc, atoi(expi), flags, now, 0);
353 return;
354 }
355 }
356 }
357 }
358 putlog(LOG_MISC, "*", "*** Malformed exemptline for %s.",
359 chan ? chan->dname : "global_exempts");
360 }
361
362 static void restore_chaninvite(struct chanset_t *chan, char *host)
363 {
364 char *expi, *add, *last, *user, *desc;
365 int flags = 0;
366
367 expi = strchr_unescape(host, ':', '\\');
368 if (expi) {
369 if (*expi == '+') {
370 flags |= MASKREC_PERM;
371 expi++;
372 }
373 add = strchr(expi, ':');
374 if (add) {
375 if (add[-1] == '*') {
376 flags |= MASKREC_STICKY;
377 add[-1] = 0;
378 } else
379 *add = 0;
380 add++;
381 if (*add == '+') {
382 last = strchr(add, ':');
383 if (last) {
384 *last = 0;
385 last++;
386 user = strchr(last, ':');
387 if (user) {
388 *user = 0;
389 user++;
390 desc = strchr(user, ':');
391 if (desc) {
392 *desc = 0;
393 desc++;
394 addmask_fully(chan, &chan->invites, &global_invites, host, user,
395 desc, atoi(expi), flags, atoi(add), atoi(last));
396 return;
397 }
398 }
399 }
400 } else {
401 desc = strchr(add, ':');
402 if (desc) {
403 *desc = 0;
404 desc++;
405 addmask_fully(chan, &chan->invites, &global_invites, host, add,
406 desc, atoi(expi), flags, now, 0);
407 return;
408 }
409 }
410 }
411 }
412 putlog(LOG_MISC, "*", "*** Malformed inviteline for %s.",
413 chan ? chan->dname : "global_invites");
414 }
415
416 static void restore_ignore(char *host)
417 {
418 char *expi, *user, *added, *desc;
419 int flags = 0;
420 struct igrec *p;
421
422 expi = strchr_unescape(host, ':', '\\');
423 if (expi) {
424 if (*expi == '+') {
425 flags |= IGREC_PERM;
426 expi++;
427 }
428 user = strchr(expi, ':');
429 if (user) {
430 *user = 0;
431 user++;
432 added = strchr(user, ':');
433 if (added) {
434 *added = 0;
435 added++;
436 desc = strchr(added, ':');
437 if (desc) {
438 *desc = 0;
439 desc++;
440 } else
441 desc = NULL;
442 } else {
443 added = "0";
444 desc = NULL;
445 }
446 p = malloc(sizeof(struct igrec));
447
448 p->next = global_ign;
449 global_ign = p;
450 p->expire = atoi(expi);
451 p->added = atoi(added);
452 p->flags = flags;
453 p->igmask = strdup(host);
454 p->user = strdup(user);
455 if (desc)
456 p->msg = strdup(desc);
457 else
458 p->msg = NULL;
459 return;
460 }
461 }
462 putlog(LOG_MISC, "*", "*** Malformed ignore line.");
463 }
464
465 void tell_user(int idx, struct userrec *u, int master)
466 {
467 char s[81], s1[81];
468 int n, l = HANDLEN - strlen(u->handle);
469 time_t now2;
470 struct chanuserrec *ch;
471 struct user_entry *ue;
472 struct laston_info *li;
473 struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
474
475 fr.global = u->flags;
476 fr.udef_global = u->flags_udef;
477 build_flags(s, &fr, NULL);
478 n = 0;
479 li = get_user(&USERENTRY_LASTON, u);
480 if (!li || !li->laston)
481 strcpy(s1, "never");
482 else {
483 now2 = now - li->laston;
484 if (now2 > 86400)
485 strftime(s1, 7, "%d %b", localtime(&li->laston));
486 else
487 strftime(s1, 6, "%H:%M", localtime(&li->laston));
488 }
489 spaces[l] = 0;
490 dprintf(idx, "%s%s %-5s%5d %-15s %s (%-10.10s)\n", u->handle, spaces,
491 get_user(&USERENTRY_PASS, u) ? "yes" : "no", n, s, s1,
492 (li && li->lastonplace) ? li->lastonplace : "nowhere");
493 spaces[l] = ' ';
494 /* channel flags? */
495 for (ch = u->chanrec; ch; ch = ch->next) {
496 fr.match = FR_CHAN | FR_GLOBAL;
497 get_user_flagrec(dcc[idx].user, &fr, ch->channel);
498 if (glob_op(fr) || chan_op(fr)) {
499 if (ch->laston == 0L)
500 strcpy(s1, "never");
501 else {
502 now2 = now - (ch->laston);
503 if (now2 > 86400)
504 strftime(s1, 7, "%d %b", localtime(&ch->laston));
505 else
506 strftime(s1, 6, "%H:%M", localtime(&ch->laston));
507 }
508 fr.match = FR_CHAN;
509 fr.chan = ch->flags;
510 fr.udef_chan = ch->flags_udef;
511 build_flags(s, &fr, NULL);
512 spaces[HANDLEN - 9] = 0;
513 dprintf(idx, "%s %-18s %-15s %s\n", spaces, ch->channel, s, s1);
514 spaces[HANDLEN - 9] = ' ';
515 if (ch->info != NULL)
516 dprintf(idx, " INFO: %s\n", ch->info);
517 }
518 }
519 /* user-defined extra fields */
520 for (ue = u->entries; ue; ue = ue->next)
521 if (!ue->name && ue->type->display)
522 ue->type->display(idx, ue);
523 }
524
525 /* show user by ident */
526 void tell_user_ident(int idx, char *id, int master)
527 {
528 struct userrec *u;
529
530 u = get_user_by_handle(userlist, id);
531 if (u == NULL)
532 u = get_user_by_host(id);
533 if (u == NULL) {
534 dprintf(idx, "%s.\n", _("Cant find anyone matching that"));
535 return;
536 }
537 spaces[HANDLEN - 6] = 0;
538 dprintf(idx, "HANDLE%s PASS NOTES FLAGS LAST\n", spaces);
539 spaces[HANDLEN - 6] = ' ';
540 tell_user(idx, u, master);
541 }
542
543 /* match string:
544 * wildcard to match nickname or hostmasks
545 * +attr to find all with attr */
546 void tell_users_match(int idx, char *mtch, int start, int limit,
547 int master, char *chname)
548 {
549 struct userrec *u;
550 int fnd = 0, cnt, nomns = 0, flags = 0;
551 struct list_type *q;
552 struct flag_record user, pls, mns;
553
554 dprintf(idx, "*** %s '%s':\n", _("Matching"), mtch);
555 cnt = 0;
556 spaces[HANDLEN - 6] = 0;
557 dprintf(idx, "HANDLE%s PASS NOTES FLAGS LAST\n", spaces);
558 spaces[HANDLEN - 6] = ' ';
559 if (start > 1)
560 dprintf(idx, "(%s %d)\n", _("skipping first"), start - 1);
561 if (strchr("+-&|", *mtch)) {
562 user.match = pls.match = FR_GLOBAL | FR_BOT | FR_CHAN;
563 break_down_flags(mtch, &pls, &mns);
564 mns.match = pls.match ^ (FR_AND | FR_OR);
565 if (!mns.global && !mns.udef_global && !mns.chan && !mns.udef_chan &&
566 !mns.bot) {
567 nomns = 1;
568 if (!pls.global && !pls.udef_global && !pls.chan && !pls.udef_chan &&
569 !pls.bot) {
570 /* happy now BB you weenie :P */
571 dprintf(idx, "Unknown flag specified for matching!!\n");
572 return;
573 }
574 }
575 if (!chname || !chname[0])
576 chname = dcc[idx].u.chat->con_chan;
577 flags = 1;
578 }
579 for (u = userlist; u; u = u->next) {
580 if (flags) {
581 get_user_flagrec(u, &user, chname);
582 if (flagrec_eq(&pls, &user)) {
583 if (nomns || !flagrec_eq(&mns, &user)) {
584 cnt++;
585 if ((cnt <= limit) && (cnt >= start))
586 tell_user(idx, u, master);
587 if (cnt == limit + 1)
588 dprintf(idx, _("(more than %d matches; list truncated)\n"), limit);
589 }
590 }
591 } else if (wild_match(mtch, u->handle)) {
592 cnt++;
593 if ((cnt <= limit) && (cnt >= start))
594 tell_user(idx, u, master);
595 if (cnt == limit + 1)
596 dprintf(idx, _("(more than %d matches; list truncated)\n"), limit);
597 } else {
598 fnd = 0;
599 for (q = get_user(&USERENTRY_HOSTS, u); q; q = q->next) {
600 if ((wild_match(mtch, q->extra)) && (!fnd)) {
601 cnt++;
602 fnd = 1;
603 if ((cnt <= limit) && (cnt >= start)) {
604 tell_user(idx, u, master);
605 }
606 if (cnt == limit + 1)
607 dprintf(idx, _("(more than %d matches; list truncated)\n"), limit);
608 }
609 }
610 }
611 }
612 dprintf(idx, _("--- Found %d match%s.\n"), cnt, cnt == 1 ? "" : "es");
613 }
614
615 void backup_userfile(void)
616 {
617 char s[125];
618
619 putlog(LOG_MISC, "*", _("Backing up user file..."));
620 snprintf(s, sizeof s, "%s~bak", userfile);
621 copyfile(userfile, s);
622 }
623
624 /*
625 * tagged lines in the user file:
626 * * OLD:
627 * # (comment)
628 * ; (comment)
629 * - hostmask(s)
630 * + email
631 * * dcc directory
632 * = comment
633 * : info line
634 * . xtra (Tcl)
635 * ! channel-specific
636 * !! global laston
637 * :: channel-specific bans
638 * NEW:
639 * *ban global bans
640 * *ignore global ignores
641 * ::#chan channel bans
642 * - entries in each
643 * <handle> begin user entry
644 * --KEY INFO - info on each
645 * NEWER:
646 * % exemptmask(s)
647 * @ Invitemask(s)
648 * *exempt global exempts
649 * *Invite global Invites
650 * && channel-specific exempts
651 * &&#chan channel exempts
652 * $$ channel-specific Invites
653 * $$#chan channel Invites
654 */
655
656 int noxtra = 0;
657 int readuserfile(char *file, struct userrec **ret)
658 {
659 char *p, buf[512], lasthand[512], *attr, *pass, *code, s1[512], *s;
660 FILE *f;
661 struct userrec *bu, *u = NULL;
662 struct chanset_t *cst = NULL;
663 int i;
664 char ignored[512];
665 struct flag_record fr;
666 struct chanuserrec *cr;
667
668 bu = (*ret);
669 ignored[0] = 0;
670 if (bu == userlist) {
671 clear_chanlist();
672 lastuser = NULL;
673 global_bans = NULL;
674 global_ign = NULL;
675 global_exempts = NULL;
676 global_invites = NULL;
677 }
678 lasthand[0] = 0;
679 f = fopen(file, "r");
680 if (f == NULL)
681 return 0;
682 noxtra = 1;
683 /* read opening comment */
684 s = buf;
685 fgets(s, 180, f);
686 if (s[1] < '4') {
687 fatal(_("Old userfile, use tclsh scripts/weed <userfile> c to convert"), 0);
688 }
689 if (s[1] > '4')
690 fatal(_("Invalid userfile format."), 0);
691 while (!feof(f)) {
692 s = buf;
693 fgets(s, 511, f);
694 if (!feof(f)) {
695 if (s[0] != '#' && s[0] != ';' && s[0]) {
696 code = newsplit(&s);
697 rmspace(s);
698 if (!strcmp(code, "-")) {
699 if (!lasthand[0])
700 continue; /* Skip this entry. */
701 if (u) { /* only break it down if there a real users */
702 p = strchr(s, ',');
703 while (p != NULL) {
704 splitc(s1, s, ',');
705 rmspace(s1);
706 if (s1[0])
707 set_user(&USERENTRY_HOSTS, u, s1);
708 p = strchr(s, ',');
709 }
710 }
711 /* channel bans are never stacked with , */
712 if (s[0]) {
713 if (lasthand[0] && strchr(CHANMETA, lasthand[0]) != NULL)
714 restore_chanban(cst, s);
715 else if (lasthand[0] == '*') {
716 if (lasthand[1] == 'i')
717 restore_ignore(s);
718 else
719 restore_chanban(NULL, s);
720 } else if (lasthand[0])
721 set_user(&USERENTRY_HOSTS, u, s);
722 }
723 } else if (!strcmp(code, "%")) { /* exemptmasks */
724 if (!lasthand[0])
725 continue; /* Skip this entry. */
726 if (s[0]) {
727 if (lasthand[0] == '#' || lasthand[0] == '+')
728 restore_chanexempt(cst,s);
729 else if (lasthand[0] == '*')
730 if (lasthand[1] == 'e')
731 restore_chanexempt(NULL, s);
732 }
733 } else if (!strcmp(code, "@")) { /* Invitemasks */
734 if (!lasthand[0])
735 continue; /* Skip this entry. */
736 if (s[0]) {
737 if (lasthand[0] == '#' || lasthand[0] == '+')
738 restore_chaninvite(cst,s);
739 else if (lasthand[0] == '*')
740 if (lasthand[1] == 'I')
741 restore_chaninvite(NULL, s);
742 }
743 } else if (!strcmp(code, "!")) {
744 /* ! #chan laston flags [info] */
745 char *chname, *st, *fl;
746
747 if (u) {
748 chname = newsplit(&s);
749 st = newsplit(&s);
750 fl = newsplit(&s);
751 rmspace(s);
752 fr.match = FR_CHAN;
753 break_down_flags(fl, &fr, 0);
754 if (findchan_by_dname(chname)) {
755 for (cr = u->chanrec; cr; cr = cr->next)
756 if (!irccmp(cr->channel, chname))
757 break;
758 if (!cr) {
759 cr = (struct chanuserrec *)
760 malloc(sizeof(struct chanuserrec));
761
762 cr->next = u->chanrec;
763 u->chanrec = cr;
764 strlcpy(cr->channel, chname, sizeof cr->channel);
765 cr->laston = atoi(st);
766 cr->flags = fr.chan;
767 cr->flags_udef = fr.udef_chan;
768 if (s[0])
769 cr->info = strdup(s);
770 else
771 cr->info = NULL;
772 }
773 }
774 }
775 } else if (!strncmp(code, "::", 2)) {
776 /* channel-specific bans */
777 strcpy(lasthand, &code[2]);
778 u = NULL;
779 if (!findchan_by_dname(lasthand)) {
780 strcpy(s1, lasthand);
781 strcat(s1, " ");
782 if (strstr(ignored, s1) == NULL) {
783 strcat(ignored, lasthand);
784 strcat(ignored, " ");
785 }
786 lasthand[0] = 0;
787 } else {
788 cst = findchan_by_dname(lasthand);
789 if (*ret == userlist) {
790 clear_masks(cst->bans);
791 cst->bans = NULL;
792 } else {
793 /* otherwise ignore any bans for this channel */
794 cst = NULL;
795 lasthand[0] = 0;
796 }
797 }
798 } else if (!strncmp(code, "&&", 2)) {
799 /* channel-specific exempts */
800 strcpy(lasthand, &code[2]);
801 u = NULL;
802 if (!findchan_by_dname(lasthand)) {
803 strcpy(s1, lasthand);
804 strcat(s1, " ");
805 if (strstr(ignored, s1) == NULL) {
806 strcat(ignored, lasthand);
807 strcat(ignored, " ");
808 }
809 lasthand[0] = 0;
810 } else {
811 cst = findchan_by_dname(lasthand);
812 if (*ret == userlist) {
813 clear_masks(cst->exempts);
814 cst->exempts = NULL;
815 } else {
816 /* otherwise ignore any exempts for this channel */
817 cst = NULL;
818 lasthand[0] = 0;
819 }
820 }
821 } else if (!strncmp(code, "$$", 2)) {
822 /* channel-specific invites */
823 strcpy(lasthand, &code[2]);
824 u = NULL;
825 if (!findchan_by_dname(lasthand)) {
826 strcpy(s1, lasthand);
827 strcat(s1, " ");
828 if (strstr(ignored, s1) == NULL) {
829 strcat(ignored, lasthand);
830 strcat(ignored, " ");
831 }
832 lasthand[0] = 0;
833 } else {
834 cst = findchan_by_dname(lasthand);
835 if (*ret == userlist) {
836 clear_masks(cst->invites);
837 cst->invites = NULL;
838 } else {
839 /* otherwise ignore any invites for this channel */
840 cst = NULL;
841 lasthand[0] = 0;
842 }
843 }
844 } else if (!strncmp(code, "--", 2)) {
845 if (u) {
846 /* new format storage */
847 struct user_entry *ue;
848 int ok = 0;
849
850 for (ue = u->entries; ue && !ok; ue = ue->next)
851 if (ue->name && !strcasecmp(code + 2, ue->name)) {
852 struct list_type *list;
853
854 list = malloc(sizeof(struct list_type));
855
856 list->next = NULL;
857 list->extra = strdup(s);
858 list_append((&ue->u.list), list);
859 ok = 1;
860 }
861 if (!ok) {
862 ue = malloc(sizeof(struct user_entry));
863
864 ue->name = malloc(strlen(code + 1));
865 ue->type = NULL;
866 strcpy(ue->name, code + 2);
867 ue->u.list = malloc(sizeof(struct list_type));
868
869 ue->u.list->next = NULL;
870 ue->u.list->extra = strdup(s);
871 list_insert((&u->entries), ue);
872 }
873 }
874 } else if (!irccmp(code, BAN_NAME)) {
875 strcpy(lasthand, code);
876 u = NULL;
877 } else if (!irccmp(code, IGNORE_NAME)) {
878 strcpy(lasthand, code);
879 u = NULL;
880 } else if (!irccmp(code, EXEMPT_NAME)) {
881 strcpy(lasthand, code);
882 u = NULL;
883 } else if (!irccmp(code, INVITE_NAME)) {
884 strcpy(lasthand, code);
885 u = NULL;
886 } else if (code[0] == '*') {
887 lasthand[0] = 0;
888 u = NULL;
889 } else {
890 pass = newsplit(&s);
891 attr = newsplit(&s);
892 rmspace(s);
893 if (!attr[0] || !pass[0]) {
894 putlog(LOG_MISC, "*", "* %s '%s'!", _("Corrupt user record"), code);
895 lasthand[0] = 0;
896 } else {
897 u = get_user_by_handle(bu, code);
898 if (u) {
899 putlog(LOG_MISC, "*", "* %s '%s'!", _("Duplicate user record"), code);
900 lasthand[0] = 0;
901 u = NULL;
902 } else {
903 fr.match = FR_GLOBAL;
904 break_down_flags(attr, &fr, 0);
905 strcpy(lasthand, code);
906 cst = NULL;
907 if (strlen(code) > HANDLEN)
908 code[HANDLEN] = 0;
909 if (strlen(pass) > 20) {
910 putlog(LOG_MISC, "*", "* %s '%s'", _("Corrupted password reset for"), code);
911 strcpy(pass, "-");
912 }
913 bu = adduser(bu, code, 0, pass,
914 sanity_check(fr.global &USER_VALID));
915
916 u = get_user_by_handle(bu, code);
917 for (i = 0; i < dcc_total; i++)
918 if (dcc[i].type && !strcasecmp(code, dcc[i].nick))
919 dcc[i].user = u;
920 u->flags_udef = fr.udef_global;
921 /* if s starts with '/' it's got file info */
922 }
923 }
924 }
925 }
926 }
927 }
928 fclose(f);
929 (*ret) = bu;
930 if (ignored[0]) {
931 putlog(LOG_MISC, "*", "%s %s", _("Ignored masks for channel(s):"), ignored);
932 }
933 putlog(LOG_MISC, "*", "Userfile loaded, unpacking...");
934 for (u = bu; u; u = u->next) {
935 struct user_entry *e;
936
937 if (!(u->flags & USER_BOT) && !strcasecmp (u->handle, myname)) {
938 putlog(LOG_MISC, "*", "(!) I have an user record, but without +b");
939 /* u->flags |= USER_BOT; */
940 }
941
942 for (e = u->entries; e; e = e->next)
943 if (e->name) {
944 struct user_entry_type *uet = find_entry_type(e->name);
945
946 if (uet) {
947 e->type = uet;
948 uet->unpack(u, e);
949 free_null(e->name);
950 }
951 }
952 }
953 noxtra = 0;
954 /* process the user data *now* */
955 return 1;
956 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23