00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 struct chanuserrec *get_chanrec(struct userrec *u, char *chname)
00026 {
00027 struct chanuserrec *ch;
00028
00029 for (ch = u->chanrec; ch; ch = ch->next)
00030 if (!rfc_casecmp(ch->channel, chname))
00031 return ch;
00032 return NULL;
00033 }
00034
00035 static struct chanuserrec *add_chanrec(struct userrec *u, char *chname)
00036 {
00037 struct chanuserrec *ch = NULL;
00038
00039 if (findchan_by_dname(chname)) {
00040 ch = user_malloc(sizeof(struct chanuserrec));
00041
00042 ch->next = u->chanrec;
00043 u->chanrec = ch;
00044 ch->info = NULL;
00045 ch->flags = 0;
00046 ch->flags_udef = 0;
00047 ch->laston = 0;
00048 strncpy(ch->channel, chname, 81);
00049 ch->channel[80] = 0;
00050 if (!noshare && !(u->flags & USER_UNSHARED))
00051 shareout(findchan_by_dname(chname), "+cr %s %s\n", u->handle, chname);
00052 }
00053 return ch;
00054 }
00055
00056 static void add_chanrec_by_handle(struct userrec *bu, char *hand, char *chname)
00057 {
00058 struct userrec *u;
00059
00060 u = get_user_by_handle(bu, hand);
00061 if (!u)
00062 return;
00063 if (!get_chanrec(u, chname))
00064 add_chanrec(u, chname);
00065 }
00066
00067 static void get_handle_chaninfo(char *handle, char *chname, char *s)
00068 {
00069 struct userrec *u;
00070 struct chanuserrec *ch;
00071
00072 u = get_user_by_handle(userlist, handle);
00073 if (u == NULL) {
00074 s[0] = 0;
00075 return;
00076 }
00077 ch = get_chanrec(u, chname);
00078 if (ch == NULL) {
00079 s[0] = 0;
00080 return;
00081 }
00082 if (ch->info == NULL) {
00083 s[0] = 0;
00084 return;
00085 }
00086 strcpy(s, ch->info);
00087 return;
00088 }
00089
00090 static void set_handle_chaninfo(struct userrec *bu, char *handle,
00091 char *chname, char *info)
00092 {
00093 struct userrec *u;
00094 struct chanuserrec *ch;
00095 struct chanset_t *cst;
00096
00097 u = get_user_by_handle(bu, handle);
00098 if (!u)
00099 return;
00100 ch = get_chanrec(u, chname);
00101 if (!ch) {
00102 add_chanrec_by_handle(bu, handle, chname);
00103 ch = get_chanrec(u, chname);
00104 }
00105 if (info) {
00106 if (strlen(info) > 80)
00107 info[80] = 0;
00108 }
00109 if (ch->info != NULL)
00110 nfree(ch->info);
00111 if (info && info[0]) {
00112 ch->info = (char *) user_malloc(strlen(info) + 1);
00113 strcpy(ch->info, info);
00114 } else
00115 ch->info = NULL;
00116 cst = findchan_by_dname(chname);
00117 if ((!noshare) && (bu == userlist) &&
00118 !(u->flags & (USER_UNSHARED | USER_BOT)) && share_greet) {
00119 shareout(cst, "chchinfo %s %s %s\n", handle, chname, info ? info : "");
00120 }
00121 }
00122
00123 static void del_chanrec(struct userrec *u, char *chname)
00124 {
00125 struct chanuserrec *ch = u->chanrec, *lst = NULL;
00126
00127 while (ch) {
00128 if (!rfc_casecmp(chname, ch->channel)) {
00129 if (lst == NULL)
00130 u->chanrec = ch->next;
00131 else
00132 lst->next = ch->next;
00133 if (ch->info != NULL)
00134 nfree(ch->info);
00135 nfree(ch);
00136 if (!noshare && !(u->flags & USER_UNSHARED))
00137 shareout(findchan_by_dname(chname), "-cr %s %s\n", u->handle, chname);
00138 return;
00139 }
00140 lst = ch;
00141 ch = ch->next;
00142 }
00143 }
00144
00145 static void set_handle_laston(char *chan, struct userrec *u, time_t n)
00146 {
00147 struct chanuserrec *ch;
00148
00149 if (!u)
00150 return;
00151 touch_laston(u, chan, n);
00152 ch = get_chanrec(u, chan);
00153 if (!ch)
00154 return;
00155 ch->laston = n;
00156 }
00157
00158
00159
00160 static int u_sticky_mask(maskrec *u, char *uhost)
00161 {
00162 for (; u; u = u->next)
00163 if (!rfc_casecmp(u->mask, uhost))
00164 return (u->flags & MASKREC_STICKY);
00165 return 0;
00166 }
00167
00168
00169
00170 static int u_setsticky_mask(struct chanset_t *chan, maskrec *u, char *uhost,
00171 int sticky, char *botcmd)
00172 {
00173 int j;
00174
00175 if (str_isdigit(uhost))
00176 j = atoi(uhost);
00177 else
00178 j = -1;
00179
00180 while (u) {
00181 if (j >= 0)
00182 j--;
00183
00184 if (!j || ((j < 0) && !rfc_casecmp(u->mask, uhost))) {
00185 if (sticky > 0)
00186 u->flags |= MASKREC_STICKY;
00187 else if (!sticky)
00188 u->flags &= ~MASKREC_STICKY;
00189 else
00190 return 0;
00191 if (!j)
00192 strcpy(uhost, u->mask);
00193
00194 if (!noshare)
00195 shareout(chan, "%s %s %d %s\n", botcmd, uhost, sticky,
00196 (chan) ? chan->dname : "");
00197 return 1;
00198 }
00199
00200 u = u->next;
00201 }
00202
00203 if (j >= 0)
00204 return -j;
00205
00206 return 0;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216 static int u_equals_mask(maskrec *u, char *mask)
00217 {
00218 for (; u; u = u->next)
00219 if (!rfc_casecmp(u->mask, mask)) {
00220 if (u->flags & MASKREC_PERM)
00221 return 2;
00222 else
00223 return 1;
00224 }
00225 return 0;
00226 }
00227
00228 static int u_match_mask(maskrec *rec, char *mask)
00229 {
00230 for (; rec; rec = rec->next)
00231 if (match_addr(rec->mask, mask))
00232 return 1;
00233 return 0;
00234 }
00235
00236 static int u_delban(struct chanset_t *c, char *who, int doit)
00237 {
00238 int j, i = 0;
00239 maskrec *t;
00240 maskrec **u = (c) ? &c->bans : &global_bans;
00241 char temp[256];
00242
00243 if (!strchr(who, '!') && str_isdigit(who)) {
00244 j = atoi(who);
00245 j--;
00246 for (; (*u) && j; u = &((*u)->next), j--);
00247 if (*u) {
00248 strncpyz(temp, (*u)->mask, sizeof temp);
00249 i = 1;
00250 } else
00251 return -j - 1;
00252 } else {
00253
00254 for (; *u && !i; u = &((*u)->next))
00255 if (!rfc_casecmp((*u)->mask, who)) {
00256 strncpyz(temp, who, sizeof temp);
00257 i = 1;
00258 break;
00259 }
00260 if (!*u)
00261 return 0;
00262 }
00263 if (i && doit) {
00264 if (!noshare) {
00265 char *mask = str_escape(temp, ':', '\\');
00266
00267 if (mask) {
00268
00269 if (c)
00270 shareout(c, "-bc %s %s\n", c->dname, mask);
00271 else
00272 shareout(NULL, "-b %s\n", mask);
00273 nfree(mask);
00274 }
00275 }
00276 if (lastdeletedmask)
00277 nfree(lastdeletedmask);
00278 lastdeletedmask = nmalloc(strlen((*u)->mask) + 1);
00279 strcpy(lastdeletedmask, (*u)->mask);
00280 nfree((*u)->mask);
00281 if ((*u)->desc)
00282 nfree((*u)->desc);
00283 if ((*u)->user)
00284 nfree((*u)->user);
00285 t = *u;
00286 *u = (*u)->next;
00287 nfree(t);
00288 }
00289 return i;
00290 }
00291
00292 static int u_delexempt(struct chanset_t *c, char *who, int doit)
00293 {
00294 int j, i = 0;
00295 maskrec *t, **u = c ? &(c->exempts) : &global_exempts;
00296 char temp[256];
00297
00298 if (!strchr(who, '!') && str_isdigit(who)) {
00299 j = atoi(who);
00300 j--;
00301 for (; (*u) && j; u = &((*u)->next), j--);
00302 if (*u) {
00303 strncpyz(temp, (*u)->mask, sizeof temp);
00304 i = 1;
00305 } else
00306 return -j - 1;
00307 } else {
00308
00309 for (; *u && !i; u = &((*u)->next))
00310 if (!rfc_casecmp((*u)->mask, who)) {
00311 strncpyz(temp, who, sizeof temp);
00312 i = 1;
00313 break;
00314 }
00315 if (!*u)
00316 return 0;
00317 }
00318 if (i && doit) {
00319 if (!noshare) {
00320 char *mask = str_escape(temp, ':', '\\');
00321
00322 if (mask) {
00323
00324 if (c)
00325 shareout(c, "-ec %s %s\n", c->dname, mask);
00326 else
00327 shareout(NULL, "-e %s\n", mask);
00328 nfree(mask);
00329 }
00330 }
00331 if (lastdeletedmask)
00332 nfree(lastdeletedmask);
00333 lastdeletedmask = nmalloc(strlen((*u)->mask) + 1);
00334 strcpy(lastdeletedmask, (*u)->mask);
00335 nfree((*u)->mask);
00336 if ((*u)->desc)
00337 nfree((*u)->desc);
00338 if ((*u)->user)
00339 nfree((*u)->user);
00340 t = *u;
00341 *u = (*u)->next;
00342 nfree(t);
00343 }
00344 return i;
00345 }
00346
00347 static int u_delinvite(struct chanset_t *c, char *who, int doit)
00348 {
00349 int j, i = 0;
00350 maskrec *t;
00351 maskrec **u = c ? &(c->invites) : &global_invites;
00352 char temp[256];
00353
00354 if (!strchr(who, '!') && str_isdigit(who)) {
00355 j = atoi(who);
00356 j--;
00357 for (; (*u) && j; u = &((*u)->next), j--);
00358 if (*u) {
00359 strncpyz(temp, (*u)->mask, sizeof temp);
00360 i = 1;
00361 } else
00362 return -j - 1;
00363 } else {
00364
00365 for (; *u && !i; u = &((*u)->next))
00366 if (!rfc_casecmp((*u)->mask, who)) {
00367 strncpyz(temp, who, sizeof temp);
00368 i = 1;
00369 break;
00370 }
00371 if (!*u)
00372 return 0;
00373 }
00374 if (i && doit) {
00375 if (!noshare) {
00376 char *mask = str_escape(temp, ':', '\\');
00377
00378 if (mask) {
00379
00380 if (c)
00381 shareout(c, "-invc %s %s\n", c->dname, mask);
00382 else
00383 shareout(NULL, "-inv %s\n", mask);
00384 nfree(mask);
00385 }
00386 }
00387 if (lastdeletedmask)
00388 nfree(lastdeletedmask);
00389 lastdeletedmask = nmalloc(strlen((*u)->mask) + 1);
00390 strcpy(lastdeletedmask, (*u)->mask);
00391 nfree((*u)->mask);
00392 if ((*u)->desc)
00393 nfree((*u)->desc);
00394 if ((*u)->user)
00395 nfree((*u)->user);
00396 t = *u;
00397 *u = (*u)->next;
00398 nfree(t);
00399 }
00400 return i;
00401 }
00402
00403
00404
00405 static int u_addban(struct chanset_t *chan, char *ban, char *from, char *note,
00406 time_t expire_time, int flags)
00407 {
00408 char host[1024], s[1024];
00409 maskrec *p = NULL, *l, **u = chan ? &chan->bans : &global_bans;
00410 module_entry *me;
00411
00412 strcpy(host, ban);
00413
00414 if ((strchr(host, '!') == NULL) && (strchr(host, '@') == NULL))
00415 strcat(host, "!*@*");
00416 else if (strchr(host, '@') == NULL)
00417 strcat(host, "@*");
00418 else if (strchr(host, '!') == NULL) {
00419 char *i = strchr(host, '@');
00420
00421 strcpy(s, i);
00422 *i = 0;
00423 strcat(host, "!*");
00424 strcat(host, s);
00425 }
00426 if ((me = module_find("server", 0, 0)) && me->funcs)
00427 simple_sprintf(s, "%s!%s", me->funcs[SERVER_BOTNAME],
00428 me->funcs[SERVER_BOTUSERHOST]);
00429 else
00430 simple_sprintf(s, "%s!%s@%s", origbotname, botuser, hostname);
00431 if (match_addr(host, s)) {
00432 putlog(LOG_MISC, "*", IRC_IBANNEDME);
00433 return 0;
00434 }
00435 if (expire_time == now)
00436 return 1;
00437
00438 for (l = *u; l; l = l->next)
00439 if (!rfc_casecmp(l->mask, host)) {
00440 p = l;
00441 break;
00442 }
00443
00444
00445 if (note[0] == '*') {
00446 flags |= MASKREC_STICKY;
00447 note++;
00448 }
00449 if ((expire_time == 0L) || (flags & MASKREC_PERM)) {
00450 flags |= MASKREC_PERM;
00451 expire_time = 0L;
00452 }
00453
00454 if (p == NULL) {
00455 p = user_malloc(sizeof(maskrec));
00456 p->next = *u;
00457 *u = p;
00458 } else {
00459 nfree(p->mask);
00460 nfree(p->user);
00461 nfree(p->desc);
00462 }
00463 p->expire = expire_time;
00464 p->added = now;
00465 p->lastactive = 0;
00466 p->flags = flags;
00467 p->mask = user_malloc(strlen(host) + 1);
00468 strcpy(p->mask, host);
00469 p->user = user_malloc(strlen(from) + 1);
00470 strcpy(p->user, from);
00471 p->desc = user_malloc(strlen(note) + 1);
00472 strcpy(p->desc, note);
00473 if (!noshare) {
00474 char *mask = str_escape(host, ':', '\\');
00475
00476 if (mask) {
00477 if (!chan)
00478 shareout(NULL, "+b %s %li %s%s %s %s\n", mask, expire_time - now,
00479 (flags & MASKREC_STICKY) ? "s" : "",
00480 (flags & MASKREC_PERM) ? "p" : "-", from, note);
00481 else
00482 shareout(chan, "+bc %s %li %s %s%s %s %s\n", mask, expire_time - now,
00483 chan->dname, (flags & MASKREC_STICKY) ? "s" : "",
00484 (flags & MASKREC_PERM) ? "p" : "-", from, note);
00485 nfree(mask);
00486 }
00487 }
00488 return 1;
00489 }
00490
00491
00492
00493 static int u_addinvite(struct chanset_t *chan, char *invite, char *from,
00494 char *note, time_t expire_time, int flags)
00495 {
00496 char host[1024], s[1024];
00497 maskrec *p = NULL, *l, **u = chan ? &chan->invites : &global_invites;
00498 module_entry *me;
00499
00500 strcpy(host, invite);
00501
00502 if ((strchr(host, '!') == NULL) && (strchr(host, '@') == NULL))
00503 strcat(host, "!*@*");
00504 else if (strchr(host, '@') == NULL)
00505 strcat(host, "@*");
00506 else if (strchr(host, '!') == NULL) {
00507 char *i = strchr(host, '@');
00508
00509 strcpy(s, i);
00510 *i = 0;
00511 strcat(host, "!*");
00512 strcat(host, s);
00513 }
00514 if ((me = module_find("server", 0, 0)) && me->funcs)
00515 simple_sprintf(s, "%s!%s", me->funcs[SERVER_BOTNAME],
00516 me->funcs[SERVER_BOTUSERHOST]);
00517 else
00518 simple_sprintf(s, "%s!%s@%s", origbotname, botuser, hostname);
00519
00520 for (l = *u; l; l = l->next)
00521 if (!rfc_casecmp(l->mask, host)) {
00522 p = l;
00523 break;
00524 }
00525
00526
00527 if (note[0] == '*') {
00528 flags |= MASKREC_STICKY;
00529 note++;
00530 }
00531 if ((expire_time == 0L) || (flags & MASKREC_PERM)) {
00532 flags |= MASKREC_PERM;
00533 expire_time = 0L;
00534 }
00535
00536 if (p == NULL) {
00537 p = user_malloc(sizeof(maskrec));
00538 p->next = *u;
00539 *u = p;
00540 } else {
00541 nfree(p->mask);
00542 nfree(p->user);
00543 nfree(p->desc);
00544 }
00545 p->expire = expire_time;
00546 p->added = now;
00547 p->lastactive = 0;
00548 p->flags = flags;
00549 p->mask = user_malloc(strlen(host) + 1);
00550 strcpy(p->mask, host);
00551 p->user = user_malloc(strlen(from) + 1);
00552 strcpy(p->user, from);
00553 p->desc = user_malloc(strlen(note) + 1);
00554 strcpy(p->desc, note);
00555 if (!noshare) {
00556 char *mask = str_escape(host, ':', '\\');
00557
00558 if (mask) {
00559 if (!chan)
00560 shareout(NULL, "+inv %s %li %s%s %s %s\n", mask, expire_time - now,
00561 (flags & MASKREC_STICKY) ? "s" : "",
00562 (flags & MASKREC_PERM) ? "p" : "-", from, note);
00563 else
00564 shareout(chan, "+invc %s %li %s %s%s %s %s\n", mask, expire_time - now,
00565 chan->dname, (flags & MASKREC_STICKY) ? "s" : "",
00566 (flags & MASKREC_PERM) ? "p" : "-", from, note);
00567 nfree(mask);
00568 }
00569 }
00570 return 1;
00571 }
00572
00573
00574
00575 static int u_addexempt(struct chanset_t *chan, char *exempt, char *from,
00576 char *note, time_t expire_time, int flags)
00577 {
00578 char host[1024], s[1024];
00579 maskrec *p = NULL, *l, **u = chan ? &chan->exempts : &global_exempts;
00580 module_entry *me;
00581
00582 strcpy(host, exempt);
00583
00584 if ((strchr(host, '!') == NULL) && (strchr(host, '@') == NULL))
00585 strcat(host, "!*@*");
00586 else if (strchr(host, '@') == NULL)
00587 strcat(host, "@*");
00588 else if (strchr(host, '!') == NULL) {
00589 char *i = strchr(host, '@');
00590
00591 strcpy(s, i);
00592 *i = 0;
00593 strcat(host, "!*");
00594 strcat(host, s);
00595 }
00596 if ((me = module_find("server", 0, 0)) && me->funcs)
00597 simple_sprintf(s, "%s!%s", me->funcs[SERVER_BOTNAME],
00598 me->funcs[SERVER_BOTUSERHOST]);
00599 else
00600 simple_sprintf(s, "%s!%s@%s", origbotname, botuser, hostname);
00601
00602 for (l = *u; l; l = l->next)
00603 if (!rfc_casecmp(l->mask, host)) {
00604 p = l;
00605 break;
00606 }
00607
00608
00609 if (note[0] == '*') {
00610 flags |= MASKREC_STICKY;
00611 note++;
00612 }
00613 if ((expire_time == 0L) || (flags & MASKREC_PERM)) {
00614 flags |= MASKREC_PERM;
00615 expire_time = 0L;
00616 }
00617
00618 if (p == NULL) {
00619 p = user_malloc(sizeof(maskrec));
00620 p->next = *u;
00621 *u = p;
00622 } else {
00623 nfree(p->mask);
00624 nfree(p->user);
00625 nfree(p->desc);
00626 }
00627 p->expire = expire_time;
00628 p->added = now;
00629 p->lastactive = 0;
00630 p->flags = flags;
00631 p->mask = user_malloc(strlen(host) + 1);
00632 strcpy(p->mask, host);
00633 p->user = user_malloc(strlen(from) + 1);
00634 strcpy(p->user, from);
00635 p->desc = user_malloc(strlen(note) + 1);
00636 strcpy(p->desc, note);
00637 if (!noshare) {
00638 char *mask = str_escape(host, ':', '\\');
00639
00640 if (mask) {
00641 if (!chan)
00642 shareout(NULL, "+e %s %li %s%s %s %s\n", mask, expire_time - now,
00643 (flags & MASKREC_STICKY) ? "s" : "",
00644 (flags & MASKREC_PERM) ? "p" : "-", from, note);
00645 else
00646 shareout(chan, "+ec %s %li %s %s%s %s %s\n", mask, expire_time - now,
00647 chan->dname, (flags & MASKREC_STICKY) ? "s" : "",
00648 (flags & MASKREC_PERM) ? "p" : "-", from, note);
00649 nfree(mask);
00650 }
00651 }
00652 return 1;
00653 }
00654
00655
00656
00657 static void display_ban(int idx, int number, maskrec *ban,
00658 struct chanset_t *chan, int show_inact)
00659 {
00660 char dates[81], s[41];
00661
00662 if (ban->added) {
00663 daysago(now, ban->added, s);
00664 sprintf(dates, "%s %s", MODES_CREATED, s);
00665 if (ban->added < ban->lastactive) {
00666 strcat(dates, ", ");
00667 strcat(dates, MODES_LASTUSED);
00668 strcat(dates, " ");
00669 daysago(now, ban->lastactive, s);
00670 strcat(dates, s);
00671 }
00672 } else
00673 dates[0] = 0;
00674 if (ban->flags & MASKREC_PERM)
00675 strcpy(s, "(perm)");
00676 else {
00677 char s1[41];
00678
00679 days(ban->expire, now, s1);
00680 sprintf(s, "(expires %s)", s1);
00681 }
00682 if (ban->flags & MASKREC_STICKY)
00683 strcat(s, " (sticky)");
00684 if (!chan || ischanban(chan, ban->mask)) {
00685 if (number >= 0)
00686 dprintf(idx, " [%3d] %s %s\n", number, ban->mask, s);
00687 else
00688 dprintf(idx, "BAN: %s %s\n", ban->mask, s);
00689 } else if (show_inact) {
00690 if (number >= 0)
00691 dprintf(idx, "! [%3d] %s %s\n", number, ban->mask, s);
00692 else
00693 dprintf(idx, "BAN (%s): %s %s\n", MODES_INACTIVE, ban->mask, s);
00694 } else
00695 return;
00696 dprintf(idx, " %s: %s\n", ban->user, ban->desc);
00697 if (dates[0])
00698 dprintf(idx, " %s\n", dates);
00699 }
00700
00701
00702
00703 static void display_exempt(int idx, int number, maskrec *exempt,
00704 struct chanset_t *chan, int show_inact)
00705 {
00706 char dates[81], s[41];
00707
00708 if (exempt->added) {
00709 daysago(now, exempt->added, s);
00710 sprintf(dates, "%s %s", MODES_CREATED, s);
00711 if (exempt->added < exempt->lastactive) {
00712 strcat(dates, ", ");
00713 strcat(dates, MODES_LASTUSED);
00714 strcat(dates, " ");
00715 daysago(now, exempt->lastactive, s);
00716 strcat(dates, s);
00717 }
00718 } else
00719 dates[0] = 0;
00720 if (exempt->flags & MASKREC_PERM)
00721 strcpy(s, "(perm)");
00722 else {
00723 char s1[41];
00724
00725 days(exempt->expire, now, s1);
00726 sprintf(s, "(expires %s)", s1);
00727 }
00728 if (exempt->flags & MASKREC_STICKY)
00729 strcat(s, " (sticky)");
00730 if (!chan || ischanexempt(chan, exempt->mask)) {
00731 if (number >= 0)
00732 dprintf(idx, " [%3d] %s %s\n", number, exempt->mask, s);
00733 else
00734 dprintf(idx, "EXEMPT: %s %s\n", exempt->mask, s);
00735 } else if (show_inact) {
00736 if (number >= 0)
00737 dprintf(idx, "! [%3d] %s %s\n", number, exempt->mask, s);
00738 else
00739 dprintf(idx, "EXEMPT (%s): %s %s\n", MODES_INACTIVE, exempt->mask, s);
00740 } else
00741 return;
00742 dprintf(idx, " %s: %s\n", exempt->user, exempt->desc);
00743 if (dates[0])
00744 dprintf(idx, " %s\n", dates);
00745 }
00746
00747
00748
00749 static void display_invite(int idx, int number, maskrec *invite,
00750 struct chanset_t *chan, int show_inact)
00751 {
00752 char dates[81], s[41];
00753
00754 if (invite->added) {
00755 daysago(now, invite->added, s);
00756 sprintf(dates, "%s %s", MODES_CREATED, s);
00757 if (invite->added < invite->lastactive) {
00758 strcat(dates, ", ");
00759 strcat(dates, MODES_LASTUSED);
00760 strcat(dates, " ");
00761 daysago(now, invite->lastactive, s);
00762 strcat(dates, s);
00763 }
00764 } else
00765 dates[0] = 0;
00766 if (invite->flags & MASKREC_PERM)
00767 strcpy(s, "(perm)");
00768 else {
00769 char s1[41];
00770
00771 days(invite->expire, now, s1);
00772 sprintf(s, "(expires %s)", s1);
00773 }
00774 if (invite->flags & MASKREC_STICKY)
00775 strcat(s, " (sticky)");
00776 if (!chan || ischaninvite(chan, invite->mask)) {
00777 if (number >= 0)
00778 dprintf(idx, " [%3d] %s %s\n", number, invite->mask, s);
00779 else
00780 dprintf(idx, "INVITE: %s %s\n", invite->mask, s);
00781 } else if (show_inact) {
00782 if (number >= 0)
00783 dprintf(idx, "! [%3d] %s %s\n", number, invite->mask, s);
00784 else
00785 dprintf(idx, "INVITE (%s): %s %s\n", MODES_INACTIVE, invite->mask, s);
00786 } else
00787 return;
00788 dprintf(idx, " %s: %s\n", invite->user, invite->desc);
00789 if (dates[0])
00790 dprintf(idx, " %s\n", dates);
00791 }
00792
00793 static void tell_bans(int idx, int show_inact, char *match)
00794 {
00795 int k = 1;
00796 char *chname;
00797 struct chanset_t *chan = NULL;
00798 maskrec *u;
00799
00800
00801 if (match[0]) {
00802 chname = newsplit(&match);
00803 if (chname[0] && (strchr(CHANMETA, chname[0]))) {
00804 chan = findchan_by_dname(chname);
00805 if (!chan) {
00806 dprintf(idx, "%s.\n", CHAN_NOSUCH);
00807 return;
00808 }
00809 } else
00810 match = chname;
00811 }
00812
00813
00814 if (!chan && !(chan = findchan_by_dname(dcc[idx].u.chat->con_chan)) &&
00815 !(chan = chanset))
00816 chan = NULL;
00817
00818 if (chan && show_inact)
00819 dprintf(idx, "%s: (! = %s %s)\n", BANS_GLOBAL,
00820 MODES_NOTACTIVE, chan->dname);
00821 else
00822 dprintf(idx, "%s:\n", BANS_GLOBAL);
00823 for (u = global_bans; u; u = u->next) {
00824 if (match[0]) {
00825 if ((match_addr(match, u->mask)) ||
00826 (wild_match(match, u->desc)) || (wild_match(match, u->user)))
00827 display_ban(idx, k, u, chan, 1);
00828 k++;
00829 } else
00830 display_ban(idx, k++, u, chan, show_inact);
00831 }
00832 if (chan) {
00833 if (show_inact)
00834 dprintf(idx, "%s %s: (! = %s, * = %s)\n",
00835 BANS_BYCHANNEL, chan->dname, MODES_NOTACTIVE2, MODES_NOTBYBOT);
00836 else
00837 dprintf(idx, "%s %s: (* = %s)\n",
00838 BANS_BYCHANNEL, chan->dname, MODES_NOTBYBOT);
00839 for (u = chan->bans; u; u = u->next) {
00840 if (match[0]) {
00841 if ((match_addr(match, u->mask)) ||
00842 (wild_match(match, u->desc)) || (wild_match(match, u->user)))
00843 display_ban(idx, k, u, chan, 1);
00844 k++;
00845 } else
00846 display_ban(idx, k++, u, chan, show_inact);
00847 }
00848 if (chan->status & CHAN_ACTIVE) {
00849 masklist *b;
00850 char s[UHOSTLEN], *s1, *s2, fill[256];
00851 int min, sec;
00852
00853 for (b = chan->channel.ban; b && b->mask[0]; b = b->next) {
00854 if ((!u_equals_mask(global_bans, b->mask)) &&
00855 (!u_equals_mask(chan->bans, b->mask))) {
00856 strcpy(s, b->who);
00857 s2 = s;
00858 s1 = splitnick(&s2);
00859 if (s1[0])
00860 sprintf(fill, "%s (%s!%s)", b->mask, s1, s2);
00861 else
00862 sprintf(fill, "%s (server %s)", b->mask, s2);
00863 if (b->timer != 0) {
00864 min = (now - b->timer) / 60;
00865 sec = (now - b->timer) - (min * 60);
00866 sprintf(s, " (active %02d:%02d)", min, sec);
00867 strcat(fill, s);
00868 }
00869 if ((!match[0]) || (match_addr(match, b->mask)))
00870 dprintf(idx, "* [%3d] %s\n", k, fill);
00871 k++;
00872 }
00873 }
00874 }
00875 }
00876 if (k == 1)
00877 dprintf(idx, "(There are no bans, permanent or otherwise.)\n");
00878 if ((!show_inact) && (!match[0]))
00879 dprintf(idx, "%s.\n", BANS_USEBANSALL);
00880 }
00881
00882 static void tell_exempts(int idx, int show_inact, char *match)
00883 {
00884 int k = 1;
00885 char *chname;
00886 struct chanset_t *chan = NULL;
00887 maskrec *u;
00888
00889
00890 if (match[0]) {
00891 chname = newsplit(&match);
00892 if (chname[0] && strchr(CHANMETA, chname[0])) {
00893 chan = findchan_by_dname(chname);
00894 if (!chan) {
00895 dprintf(idx, "%s.\n", CHAN_NOSUCH);
00896 return;
00897 }
00898 } else
00899 match = chname;
00900 }
00901
00902
00903 if (!chan && !(chan = findchan_by_dname(dcc[idx].u.chat->con_chan)) &&
00904 !(chan = chanset))
00905 chan = NULL;
00906
00907 if (chan && show_inact)
00908 dprintf(idx, "%s: (! = %s %s)\n", EXEMPTS_GLOBAL,
00909 MODES_NOTACTIVE, chan->dname);
00910 else
00911 dprintf(idx, "%s:\n", EXEMPTS_GLOBAL);
00912 for (u = global_exempts; u; u = u->next) {
00913 if (match[0]) {
00914 if ((match_addr(match, u->mask)) ||
00915 (wild_match(match, u->desc)) || (wild_match(match, u->user)))
00916 display_exempt(idx, k, u, chan, 1);
00917 k++;
00918 } else
00919 display_exempt(idx, k++, u, chan, show_inact);
00920 }
00921 if (chan) {
00922 if (show_inact)
00923 dprintf(idx, "%s %s: (! = %s, * = %s)\n", EXEMPTS_BYCHANNEL,
00924 chan->dname, MODES_NOTACTIVE2, MODES_NOTBYBOT);
00925 else
00926 dprintf(idx, "%s %s: (* = %s)\n",
00927 EXEMPTS_BYCHANNEL, chan->dname, MODES_NOTBYBOT);
00928 for (u = chan->exempts; u; u = u->next) {
00929 if (match[0]) {
00930 if ((match_addr(match, u->mask)) ||
00931 (wild_match(match, u->desc)) || (wild_match(match, u->user)))
00932 display_exempt(idx, k, u, chan, 1);
00933 k++;
00934 } else
00935 display_exempt(idx, k++, u, chan, show_inact);
00936 }
00937 if (chan->status & CHAN_ACTIVE) {
00938 masklist *e;
00939 char s[UHOSTLEN], *s1, *s2, fill[256];
00940 int min, sec;
00941
00942 for (e = chan->channel.exempt; e && e->mask[0]; e = e->next) {
00943 if ((!u_equals_mask(global_exempts, e->mask)) &&
00944 (!u_equals_mask(chan->exempts, e->mask))) {
00945 strcpy(s, e->who);
00946 s2 = s;
00947 s1 = splitnick(&s2);
00948 if (s1[0])
00949 sprintf(fill, "%s (%s!%s)", e->mask, s1, s2);
00950 else
00951 sprintf(fill, "%s (server %s)", e->mask, s2);
00952 if (e->timer != 0) {
00953 min = (now - e->timer) / 60;
00954 sec = (now - e->timer) - (min * 60);
00955 sprintf(s, " (active %02d:%02d)", min, sec);
00956 strcat(fill, s);
00957 }
00958 if ((!match[0]) || (match_addr(match, e->mask)))
00959 dprintf(idx, "* [%3d] %s\n", k, fill);
00960 k++;
00961 }
00962 }
00963 }
00964 }
00965 if (k == 1)
00966 dprintf(idx, "(There are no ban exempts, permanent or otherwise.)\n");
00967 if ((!show_inact) && (!match[0]))
00968 dprintf(idx, "%s.\n", EXEMPTS_USEEXEMPTSALL);
00969 }
00970
00971 static void tell_invites(int idx, int show_inact, char *match)
00972 {
00973 int k = 1;
00974 char *chname;
00975 struct chanset_t *chan = NULL;
00976 maskrec *u;
00977
00978
00979 if (match[0]) {
00980 chname = newsplit(&match);
00981 if (chname[0] && strchr(CHANMETA, chname[0])) {
00982 chan = findchan_by_dname(chname);
00983 if (!chan) {
00984 dprintf(idx, "%s.\n", CHAN_NOSUCH);
00985 return;
00986 }
00987 } else
00988 match = chname;
00989 }
00990
00991
00992 if (!chan && !(chan = findchan_by_dname(dcc[idx].u.chat->con_chan)) &&
00993 !(chan = chanset))
00994 chan = NULL;
00995
00996 if (chan && show_inact)
00997 dprintf(idx, "%s: (! = %s %s)\n", INVITES_GLOBAL,
00998 MODES_NOTACTIVE, chan->dname);
00999 else
01000 dprintf(idx, "%s:\n", INVITES_GLOBAL);
01001 for (u = global_invites; u; u = u->next) {
01002 if (match[0]) {
01003 if ((match_addr(match, u->mask)) ||
01004 (wild_match(match, u->desc)) || (wild_match(match, u->user)))
01005 display_invite(idx, k, u, chan, 1);
01006 k++;
01007 } else
01008 display_invite(idx, k++, u, chan, show_inact);
01009 }
01010 if (chan) {
01011 if (show_inact)
01012 dprintf(idx, "%s %s: (! = %s, * = %s)\n", INVITES_BYCHANNEL,
01013 chan->dname, MODES_NOTACTIVE2, MODES_NOTBYBOT);
01014 else
01015 dprintf(idx, "%s %s: (* = %s)\n",
01016 INVITES_BYCHANNEL, chan->dname, MODES_NOTBYBOT);
01017 for (u = chan->invites; u; u = u->next) {
01018 if (match[0]) {
01019 if ((match_addr(match, u->mask)) ||
01020 (wild_match(match, u->desc)) || (wild_match(match, u->user)))
01021 display_invite(idx, k, u, chan, 1);
01022 k++;
01023 } else
01024 display_invite(idx, k++, u, chan, show_inact);
01025 }
01026 if (chan->status & CHAN_ACTIVE) {
01027 masklist *i;
01028 char s[UHOSTLEN], *s1, *s2, fill[256];
01029 int min, sec;
01030
01031 for (i = chan->channel.invite; i && i->mask[0]; i = i->next) {
01032 if ((!u_equals_mask(global_invites, i->mask)) &&
01033 (!u_equals_mask(chan->invites, i->mask))) {
01034 strcpy(s, i->who);
01035 s2 = s;
01036 s1 = splitnick(&s2);
01037 if (s1[0])
01038 sprintf(fill, "%s (%s!%s)", i->mask, s1, s2);
01039 else
01040 sprintf(fill, "%s (server %s)", i->mask, s2);
01041 if (i->timer != 0) {
01042 min = (now - i->timer) / 60;
01043 sec = (now - i->timer) - (min * 60);
01044 sprintf(s, " (active %02d:%02d)", min, sec);
01045 strcat(fill, s);
01046 }
01047 if ((!match[0]) || (match_addr(match, i->mask)))
01048 dprintf(idx, "* [%3d] %s\n", k, fill);
01049 k++;
01050 }
01051 }
01052 }
01053 }
01054 if (k == 1)
01055 dprintf(idx, "(There are no invites, permanent or otherwise.)\n");
01056 if ((!show_inact) && (!match[0]))
01057 dprintf(idx, "%s.\n", INVITES_USEINVITESALL);
01058 }
01059
01060
01061
01062 static int write_bans(FILE *f, int idx)
01063 {
01064 struct chanset_t *chan;
01065 maskrec *b;
01066 char *mask;
01067 long expire, added;
01068
01069 if (global_bans)
01070 if (fprintf(f, BAN_NAME " - -\n") == EOF)
01071 return 0;
01072 for (b = global_bans; b; b = b->next) {
01073 mask = str_escape(b->mask, ':', '\\');
01074 expire = b->expire;
01075 added = b->added;
01076 if (!mask ||
01077 fprintf(f, "- %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask,
01078 (b->flags & MASKREC_PERM) ? "+" : "", expire,
01079 (b->flags & MASKREC_STICKY) ? "*" : "", added,
01080 (long) b->lastactive, b->user ? b->user : botnetnick,
01081 b->desc ? b->desc : "requested") == EOF) {
01082 if (mask)
01083 nfree(mask);
01084 return 0;
01085 }
01086 nfree(mask);
01087 }
01088 for (chan = chanset; chan; chan = chan->next)
01089 if ((idx < 0) || (chan->status & CHAN_SHARED)) {
01090 struct flag_record fr = { FR_CHAN | FR_GLOBAL | FR_BOT, 0, 0, 0, 0, 0 };
01091
01092 if (idx >= 0)
01093 get_user_flagrec(dcc[idx].user, &fr, chan->dname);
01094 else
01095 fr.chan = BOT_SHARE;
01096 if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
01097 if (fprintf(f, "::%s bans\n", chan->dname) == EOF)
01098 return 0;
01099 for (b = chan->bans; b; b = b->next) {
01100 mask = str_escape(b->mask, ':', '\\');
01101 expire = b->expire;
01102 added = b->added;
01103 if (!mask ||
01104 fprintf(f, "- %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask,
01105 (b->flags & MASKREC_PERM) ? "+" : "", expire,
01106 (b->flags & MASKREC_STICKY) ? "*" : "", added,
01107 (long) b->lastactive, b->user ? b->user : botnetnick,
01108 b->desc ? b->desc : "requested") == EOF) {
01109 if (mask)
01110 nfree(mask);
01111 return 0;
01112 }
01113 nfree(mask);
01114 }
01115 }
01116 }
01117 return 1;
01118 }
01119
01120
01121
01122 static int write_exempts(FILE *f, int idx)
01123 {
01124 struct chanset_t *chan;
01125 maskrec *e;
01126 char *mask;
01127 long expire, added;
01128
01129 if (global_exempts)
01130 if (fprintf(f, EXEMPT_NAME " - -\n") == EOF)
01131 return 0;
01132 for (e = global_exempts; e; e = e->next) {
01133 mask = str_escape(e->mask, ':', '\\');
01134 expire = e->expire;
01135 added = e->added;
01136 if (!mask ||
01137 fprintf(f, "%s %s:%s%lu%s:+%lu:%lu:%s:%s\n", "%", mask,
01138 (e->flags & MASKREC_PERM) ? "+" : "", expire,
01139 (e->flags & MASKREC_STICKY) ? "*" : "", added,
01140 (long) e->lastactive, e->user ? e->user : botnetnick,
01141 e->desc ? e->desc : "requested") == EOF) {
01142 if (mask)
01143 nfree(mask);
01144 return 0;
01145 }
01146 nfree(mask);
01147 }
01148 for (chan = chanset; chan; chan = chan->next)
01149 if ((idx < 0) || (chan->status & CHAN_SHARED)) {
01150 struct flag_record fr = { FR_CHAN | FR_GLOBAL | FR_BOT, 0, 0, 0, 0, 0 };
01151
01152 if (idx >= 0)
01153 get_user_flagrec(dcc[idx].user, &fr, chan->dname);
01154 else
01155 fr.chan = BOT_SHARE;
01156 if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
01157 if (fprintf(f, "&&%s exempts\n", chan->dname) == EOF)
01158 return 0;
01159 for (e = chan->exempts; e; e = e->next) {
01160 mask = str_escape(e->mask, ':', '\\');
01161 expire = e->expire;
01162 added = e->added;
01163 if (!mask ||
01164 fprintf(f, "%s %s:%s%lu%s:+%lu:%lu:%s:%s\n", "%", mask,
01165 (e->flags & MASKREC_PERM) ? "+" : "", expire,
01166 (e->flags & MASKREC_STICKY) ? "*" : "", added,
01167 (long) e->lastactive, e->user ? e->user : botnetnick,
01168 e->desc ? e->desc : "requested") == EOF) {
01169 if (mask)
01170 nfree(mask);
01171 return 0;
01172 }
01173 nfree(mask);
01174 }
01175 }
01176 }
01177 return 1;
01178 }
01179
01180
01181
01182 static int write_invites(FILE *f, int idx)
01183 {
01184 struct chanset_t *chan;
01185 maskrec *ir;
01186 char *mask;
01187 long expire, added;
01188
01189 if (global_invites)
01190 if (fprintf(f, INVITE_NAME " - -\n") == EOF)
01191 return 0;
01192 for (ir = global_invites; ir; ir = ir->next) {
01193 mask = str_escape(ir->mask, ':', '\\');
01194 expire = ir->expire;
01195 added = ir->added;
01196 if (!mask ||
01197 fprintf(f, "@ %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask,
01198 (ir->flags & MASKREC_PERM) ? "+" : "", expire,
01199 (ir->flags & MASKREC_STICKY) ? "*" : "", added,
01200 (long) ir->lastactive, ir->user ? ir->user : botnetnick,
01201 ir->desc ? ir->desc : "requested") == EOF) {
01202 if (mask)
01203 nfree(mask);
01204 return 0;
01205 }
01206 nfree(mask);
01207 }
01208 for (chan = chanset; chan; chan = chan->next)
01209 if ((idx < 0) || (chan->status & CHAN_SHARED)) {
01210 struct flag_record fr = { FR_CHAN | FR_GLOBAL | FR_BOT, 0, 0, 0, 0, 0 };
01211
01212 if (idx >= 0)
01213 get_user_flagrec(dcc[idx].user, &fr, chan->dname);
01214 else
01215 fr.chan = BOT_SHARE;
01216 if ((fr.chan & BOT_SHARE) || (fr.bot & BOT_GLOBAL)) {
01217 if (fprintf(f, "$$%s invites\n", chan->dname) == EOF)
01218 return 0;
01219 for (ir = chan->invites; ir; ir = ir->next) {
01220 mask = str_escape(ir->mask, ':', '\\');
01221 expire = ir->expire;
01222 added = ir->added;
01223 if (!mask ||
01224 fprintf(f, "@ %s:%s%lu%s:+%lu:%lu:%s:%s\n", mask,
01225 (ir->flags & MASKREC_PERM) ? "+" : "", expire,
01226 (ir->flags & MASKREC_STICKY) ? "*" : "", added,
01227 (long) ir->lastactive, ir->user ? ir->user : botnetnick,
01228 ir->desc ? ir->desc : "requested") == EOF) {
01229 if (mask)
01230 nfree(mask);
01231 return 0;
01232 }
01233 nfree(mask);
01234 }
01235 }
01236 }
01237 return 1;
01238 }
01239
01240 static void channels_writeuserfile(void)
01241 {
01242 char s[1024];
01243 FILE *f;
01244 int ret = 0;
01245
01246 simple_sprintf(s, "%s~new", userfile);
01247 f = fopen(s, "a");
01248 if (f) {
01249 ret = write_bans(f, -1);
01250 ret += write_exempts(f, -1);
01251 ret += write_invites(f, -1);
01252 fclose(f);
01253 }
01254 if (ret < 3)
01255 putlog(LOG_MISC, "*", USERF_ERRWRITE);
01256 write_channels();
01257 }
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269 static int expired_mask(struct chanset_t *chan, char *who)
01270 {
01271 memberlist *m, *m2;
01272 char buf[UHOSTLEN], *snick, *sfrom;
01273 struct userrec *u;
01274
01275
01276 if (force_expire)
01277 return 1;
01278
01279 strcpy(buf, who);
01280 sfrom = buf;
01281 snick = splitnick(&sfrom);
01282
01283 if (!snick[0])
01284 return 1;
01285
01286 m = ismember(chan, snick);
01287 if (!m)
01288 for (m2 = chan->channel.member; m2 && m2->nick[0]; m2 = m2->next)
01289 if (!egg_strcasecmp(sfrom, m2->userhost)) {
01290 m = m2;
01291 break;
01292 }
01293
01294 if (!m || !chan_hasop(m) || !rfc_casecmp(m->nick, botname))
01295 return 1;
01296
01297
01298
01299
01300
01301 if (m->user)
01302 u = m->user;
01303 else {
01304 simple_sprintf(buf, "%s!%s", m->nick, m->userhost);
01305 u = get_user_by_host(buf);
01306 }
01307
01308 if (u && u->flags & USER_BOT)
01309 return 0;
01310 else
01311 return 1;
01312 }
01313
01314
01315
01316 static void check_expired_bans(void)
01317 {
01318 maskrec *u, *u2;
01319 struct chanset_t *chan;
01320 masklist *b;
01321
01322 for (u = global_bans; u; u = u2) {
01323 u2 = u->next;
01324 if (!(u->flags & MASKREC_PERM) && (now >= u->expire)) {
01325 putlog(LOG_MISC, "*", "%s %s (%s)", BANS_NOLONGER, u->mask, MISC_EXPIRED);
01326 for (chan = chanset; chan; chan = chan->next)
01327 for (b = chan->channel.ban; b->mask[0]; b = b->next)
01328 if (!rfc_casecmp(b->mask, u->mask) &&
01329 expired_mask(chan, b->who) && b->timer != now) {
01330 add_mode(chan, '-', 'b', u->mask);
01331 b->timer = now;
01332 }
01333 u_delban(NULL, u->mask, 1);
01334 }
01335 }
01336
01337 for (chan = chanset; chan; chan = chan->next) {
01338 for (u = chan->bans; u; u = u2) {
01339 u2 = u->next;
01340 if (!(u->flags & MASKREC_PERM) && (now >= u->expire)) {
01341 putlog(LOG_MISC, "*", "%s %s %s %s (%s)", BANS_NOLONGER,
01342 u->mask, MISC_ONLOCALE, chan->dname, MISC_EXPIRED);
01343 for (b = chan->channel.ban; b->mask[0]; b = b->next)
01344 if (!rfc_casecmp(b->mask, u->mask) &&
01345 expired_mask(chan, b->who) && b->timer != now) {
01346 add_mode(chan, '-', 'b', u->mask);
01347 b->timer = now;
01348 }
01349 u_delban(chan, u->mask, 1);
01350 }
01351 }
01352 }
01353 }
01354
01355
01356
01357 static void check_expired_exempts(void)
01358 {
01359 maskrec *u, *u2;
01360 struct chanset_t *chan;
01361 masklist *b, *e;
01362 int match;
01363
01364 if (!use_exempts)
01365 return;
01366 for (u = global_exempts; u; u = u2) {
01367 u2 = u->next;
01368 if (!(u->flags & MASKREC_PERM) && (now >= u->expire)) {
01369 putlog(LOG_MISC, "*", "%s %s (%s)", EXEMPTS_NOLONGER,
01370 u->mask, MISC_EXPIRED);
01371 for (chan = chanset; chan; chan = chan->next) {
01372 match = 0;
01373 b = chan->channel.ban;
01374 while (b->mask[0] && !match) {
01375 if (mask_match(b->mask, u->mask))
01376 match = 1;
01377 else
01378 b = b->next;
01379 }
01380 if (match)
01381 putlog(LOG_MISC, chan->dname,
01382 "Exempt not expired on channel %s. Ban still set!",
01383 chan->dname);
01384 else
01385 for (e = chan->channel.exempt; e->mask[0]; e = e->next)
01386 if (!rfc_casecmp(e->mask, u->mask) &&
01387 expired_mask(chan, e->who) && e->timer != now) {
01388 add_mode(chan, '-', 'e', u->mask);
01389 e->timer = now;
01390 }
01391 }
01392 u_delexempt(NULL, u->mask, 1);
01393 }
01394 }
01395
01396 for (chan = chanset; chan; chan = chan->next) {
01397 for (u = chan->exempts; u; u = u2) {
01398 u2 = u->next;
01399 if (!(u->flags & MASKREC_PERM) && (now >= u->expire)) {
01400 match = 0;
01401 b = chan->channel.ban;
01402 while (b->mask[0] && !match) {
01403 if (mask_match(b->mask, u->mask))
01404 match = 1;
01405 else
01406 b = b->next;
01407 }
01408 if (match)
01409 putlog(LOG_MISC, chan->dname,
01410 "Exempt not expired on channel %s. Ban still set!",
01411 chan->dname);
01412 else {
01413 putlog(LOG_MISC, "*", "%s %s %s %s (%s)", EXEMPTS_NOLONGER,
01414 u->mask, MISC_ONLOCALE, chan->dname, MISC_EXPIRED);
01415 for (e = chan->channel.exempt; e->mask[0]; e = e->next)
01416 if (!rfc_casecmp(e->mask, u->mask) &&
01417 expired_mask(chan, e->who) && e->timer != now) {
01418 add_mode(chan, '-', 'e', u->mask);
01419 e->timer = now;
01420 }
01421 u_delexempt(chan, u->mask, 1);
01422 }
01423 }
01424 }
01425 }
01426 }
01427
01428
01429
01430 static void check_expired_invites(void)
01431 {
01432 maskrec *u, *u2;
01433 struct chanset_t *chan;
01434 masklist *b;
01435
01436 if (!use_invites)
01437 return;
01438 for (u = global_invites; u; u = u2) {
01439 u2 = u->next;
01440 if (!(u->flags & MASKREC_PERM) && (now >= u->expire)) {
01441 putlog(LOG_MISC, "*", "%s %s (%s)", INVITES_NOLONGER,
01442 u->mask, MISC_EXPIRED);
01443 for (chan = chanset; chan; chan = chan->next)
01444 if (!(chan->channel.mode & CHANINV))
01445 for (b = chan->channel.invite; b->mask[0]; b = b->next)
01446 if (!rfc_casecmp(b->mask, u->mask) &&
01447 expired_mask(chan, b->who) && b->timer != now) {
01448 add_mode(chan, '-', 'I', u->mask);
01449 b->timer = now;
01450 }
01451 u_delinvite(NULL, u->mask, 1);
01452 }
01453 }
01454
01455 for (chan = chanset; chan; chan = chan->next) {
01456 for (u = chan->invites; u; u = u2) {
01457 u2 = u->next;
01458 if (!(u->flags & MASKREC_PERM) && (now >= u->expire)) {
01459 putlog(LOG_MISC, "*", "%s %s %s %s (%s)", INVITES_NOLONGER,
01460 u->mask, MISC_ONLOCALE, chan->dname, MISC_EXPIRED);
01461 if (!(chan->channel.mode & CHANINV))
01462 for (b = chan->channel.invite; b->mask[0]; b = b->next)
01463 if (!rfc_casecmp(b->mask, u->mask) &&
01464 expired_mask(chan, b->who) && b->timer != now) {
01465 add_mode(chan, '-', 'I', u->mask);
01466 b->timer = now;
01467 }
01468 u_delinvite(chan, u->mask, 1);
01469 }
01470 }
01471 }
01472 }