Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

akill.c

Go to the documentation of this file.
00001 
00015 /*
00016  * Copyright (c) 1996-1997 Chip Norkus
00017  * Copyright (c) 1997 Max Byrd
00018  * Copyright (c) 1997 Greg Poma
00019  * Copyright (c) 2000-2001 James Hess
00020  * All rights reserved.
00021  *
00022  * Redistribution and use in source and binary forms, with or without
00023  * modification, are permitted provided that the following conditions
00024  * are met:
00025  * 1. Redistributions of source code must retain the above copyright
00026  *    notice, this list of conditions and the following disclaimer.
00027  * 2. Redistributions in binary form must reproduce the above copyright
00028  *    notice, this list of conditions and the following disclaimer in the
00029  *    documentation and/or other materials provided with the distribution.
00030  * 3. Neither the name of the authors nor the names of its contributors
00031  *    may be used to endorse or promote products derived from this software
00032  *    without specific prior written permission.
00033  *
00034  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
00035  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00036  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00037  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
00038  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00039  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00040  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00041  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00042  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00043  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00044  * SUCH DAMAGE.
00045  */
00046 
00047 #include "services.h"
00048 #include "operserv.h"
00049 #include "hash.h"
00050 #include "email.h"
00051 #include "log.h"
00052 #include "sipc.h"
00053 
00054 /*******************************************************************/
00055 
00060 /*******************************************************************/
00061 
00062 void saveKlineQueue();
00063 void loadKlineQueue();
00064 
00069 unsigned long top_akill_stamp = 0;
00070 
00072 static struct akill *firstBanItem = NULL;
00073 
00074 EmailMessage kline_email;       
00075 EmailString kline_enforce_buf;  
00076 EmailMessage ops_email;         
00077 EmailString ops_enforce_buf;    
00078 int kline_email_nitems = 0;     
00079 int ops_email_nitems = 0;       
00080 
00081 time_t kline_e_last_time;       
00082 time_t ops_e_last_time;         
00083 
00084 
00085 /*****************************************************************************/
00086 
00087 int IpcConnectType::sendAkills(int akillType, const char *searchText)
00088 {
00089     struct akill *ak;
00090     char mask[NICKLEN + USERLEN + HOSTLEN + 3];
00091     char length[16];
00092     int x = 0;
00093 
00094     if (!firstBanItem)
00095         return 0;
00096 
00097     for (ak = firstBanItem; ak; ak = ak->next) {
00098         if (ak->type == akillType || ak->type == 0) {
00099             strcpy(mask, ak->nick);
00100             strcat(mask, "!");
00101             strcat(mask, ak->user);
00102             strcat(mask, "@");
00103             strcat(mask, ak->host);
00104 
00105             if (searchText && strcmp(mask, searchText) )
00106                 continue;
00107 
00108             if (ak->unset)
00109                 sprintf(length, "%luh",
00110                         (long)(ak->unset - ak->set) / 3600);
00111             else
00112                 strcpy(length, "forever");
00113 
00114             fWriteLn("DATA %ld %ld %s %s :%s", ak->set, ak->unset, length, mask, ak->reason);
00115             x++;
00116         }
00117     }
00118     return x;
00119 }
00120 
00129 void listAkills(char *from, char type)
00130 {
00131     struct akill *ak;
00132     char mask[NICKLEN + USERLEN + HOSTLEN + 3];
00133     char length[16];
00134     struct tm *t;
00135 
00136     if (!firstBanItem) {
00137         sSend(":%s NOTICE %s :There are no autokills/ignores.", OperServ,
00138               from);
00139         return;
00140     }
00141     sSend(":%s NOTICE %s :%-14s %-8s %-20s %-10s %s", OperServ, from,
00142           "SetTime", "Length", "Mask", "Set By", "Reason");
00143     for (ak = firstBanItem; ak; ak = ak->next) {
00144         if (ak->type == type || ak->type == 0) {
00145             strcpy(mask, ak->nick);
00146             strcat(mask, "!");
00147             strcat(mask, ak->user);
00148             strcat(mask, "@");
00149             strcat(mask, ak->host);
00150 
00151             t = localtime(&(ak->set));
00152 
00153             if (ak->unset)
00154                 sprintf(length, "%luh",
00155                         (long)(ak->unset - ak->set) / 3600);
00156             else
00157                 strcpy(length, "forever");
00158 
00159             sSend
00160                 (":%s NOTICE %s :%02d/%02d/%02d-%02d:%02d %-8s %-20s %-10s %s",
00161                  OperServ, from, t->tm_mon + 1, t->tm_mday,
00162                  (t->tm_year % 100), t->tm_hour, t->tm_min, length, mask,
00163                  ak->setby, ak->reason);
00164         }
00165     }
00166     sSend(":%s NOTICE %s :End of list.", OperServ, from);
00167 }
00168 
00179 int isAKilled(char *nick, char *user, char *host)
00180 {
00181     struct akill *ak;
00182 
00183     for (ak = firstBanItem; ak; ak = ak->next) {
00184         if (!match(ak->nick, nick) && !match(ak->user, user)
00185             && !match(ak->host, host) && (ak->type == A_AKILL))
00186             return 1;
00187     }
00188     return 0;
00189 }
00190 
00191 
00192 struct akill* getAkill(char *nick, char *user, char *host)
00193 {
00194     struct akill *ak;
00195 
00196     for (ak = firstBanItem; ak; ak = ak->next) {
00197         if (!match(ak->nick, nick) && !match(ak->user, user)
00198             && !match(ak->host, host) && (ak->type == A_AKILL))
00199             return ak;
00200     }
00201     return (struct akill*)0;
00202 }
00203 
00204 long getAkillId(struct akill* ak)
00205 {
00206     return ak->id;
00207 }
00208 
00209 struct akill* getAhurt(char *nick, char *user, char *host)
00210 {
00211     struct akill *ak;
00212 
00213     for (ak = firstBanItem; ak; ak = ak->next) {
00214         if (!match(ak->nick, nick) && !match(ak->user, user)
00215             && !match(ak->host, host) && (ak->type == A_AHURT))
00216             return ak;
00217     }
00218     return (struct akill*)0;
00219 }
00220 
00221 char* getAkReason(struct akill *ak)
00222 {
00223     return ak->reason;
00224 }
00225 
00238 char* applyAkill(char* nick, char* user, char* host, struct akill* ak)
00239 {
00240     char buf[1024];
00241 
00242 /*  if (!match(ak->nick, nick) && !match(ak->user, user)
00243         && !match(ak->host, host)) */
00244     {
00245         char length[16];
00246 
00247         /* if the nick is wildcarded, reset the akill */
00248         if (!strcmp(ak->nick, "*")) {
00249             if (ak->unset)
00250                 sprintf(length, "%luh",
00251                     (long)(ak->unset - ak->set) / 3600);
00252             else
00253                 strcpy(length, "forever");
00254 
00255         if (ak->type == A_AKILL)
00256             sSend
00257                 (":%s AKILL %s %s :[#%.6x] Autokilled for %s [%s]",
00258                  myname, ak->host, ak->user, ak->id, length,
00259                  ak->reason);
00260         else if (ak->type == A_AHURT)
00261             sSend(":%s AHURT %s %s :[#%.6x] Autohurt for %s [%s]",
00262                   myname, ak->host, ak->user, ak->id, length,
00263                   ak->reason);
00264         }
00265 
00266         if (ak->type == A_AKILL)
00267             sprintf(buf,
00268                 "[#%.6x] Autokill %s!%s@%s triggered by user %s!%s@%s at %s\n",
00269                 ak->id, ak->nick, ak->user, ak->host, nick, user,
00270                 host, ctime(&CTime));
00271         else if (ak->type == A_AHURT)
00272             sprintf(buf,
00273                 "[#%.6x] Autohurt %s!%s@%s triggered by user %s!%s@%s at %s\n",
00274                 ak->id, ak->nick, ak->user, ak->host, nick, user,
00275                 host, ctime(&CTime));
00276 #ifdef AKILLMAILTO
00277         kline_enforce_buf += buf;
00278         kline_email_nitems++;
00279 #endif
00280 
00281 #ifdef OPSMAILTO
00282         ops_enforce_buf += buf;
00283         ops_email_nitems++;
00284 #endif
00285 
00286     if (ak->type == A_AKILL)
00287             return ak->reason;
00288     }
00289 
00290     return NULL;
00291 }
00292 
00303 int isAHurt(char *nick, char *user, char *host)
00304 {
00305 #ifdef ENABLE_AHURT
00306     struct akill *ak;
00307 
00308     for (ak = firstBanItem; ak; ak = ak->next) {
00309         if (!match(ak->nick, nick) && !match(ak->user, user)
00310             && !match(ak->host, host) && (ak->type == A_AHURT))
00311             return 1;
00312     }
00313 #endif
00314     return 0;
00315 }
00316 
00327 int isIgnored(char *nick, char *user, char *host)
00328 {
00329     struct akill *ak;
00330 
00331     for (ak = firstBanItem; ak; ak = ak->next) {
00332         if (!match(ak->nick, nick) && !match(ak->user, user)
00333             && !match(ak->host, host) && (ak->type == A_IGNORE))
00334             return 1;
00335     }
00336     return 0;
00337 }
00338 
00339 
00349 void checkAkillAllUsers(struct akill *ak)
00350 {
00351     HashKeyVal hashEnt;
00352     char ak_pattern[NICKLEN + USERLEN + HOSTLEN + 25];
00353     char user_pattern[NICKLEN + USERLEN + HOSTLEN + 25];
00354     char buf[MAXBUF];
00355     UserList *tmpnick, *tmpnext;
00356 
00357     if (!ak || (ak->type != A_AKILL && ak->type != A_AHURT))
00358         return;
00359 #ifndef IRCD_HURTSET
00360     if (ak->type == A_AHURT)
00361         return;
00362 #endif
00363     if (!ak->nick || !ak->user || !ak->host)
00364         return;
00365 
00366     snprintf(ak_pattern, sizeof(ak_pattern), "%s!%s@%s", ak->nick,
00367              ak->user, ak->host);
00368 
00369     for (hashEnt = 0; hashEnt < NICKHASHSIZE; hashEnt++)
00370         for (tmpnick = LIST_FIRST(&UserHash[hashEnt]); tmpnick != NULL;
00371              tmpnick = tmpnext) {
00372             tmpnext = LIST_NEXT(tmpnick, ul_lst);
00373             if (tmpnick->oflags & NISOPER)
00374                 continue;
00375             if (ak->type == A_AHURT
00376                 && (tmpnick->caccess >= 2 && tmpnick->reg
00377                     && ((tmpnick->reg->flags & NBYPASS)
00378                         || (tmpnick->reg->opflags))))
00379                  continue;
00380 
00381             snprintf(user_pattern, sizeof(user_pattern), "%s!%s@%s",
00382                      tmpnick->nick, tmpnick->user, tmpnick->host);
00383             if (match(ak_pattern, user_pattern))
00384                 continue;
00385 
00386             if (ak->type == A_AHURT) 
00387             {
00388                 /* sSend(":%s HURTSET %s 3 :AutoHurt User", OperServ,
00389                       tmpnick->nick); */
00390                 /* tmpnick->oflags |= NISAHURT; */
00391             }
00392             if (ak->type == A_AKILL) {
00393                 char inick[NICKLEN + 1];
00394                 strncpyzt(inick, tmpnick->nick, sizeof(inick));
00395                 sSend(":%s KILL %s :%s!%s (AKilled: %s)", services[1].name,
00396                       tmpnick->nick, services[1].host, services[1].name,
00397                       ak->reason);
00398 
00399                 sprintf(buf,
00400                         "Autokill %s!%s@%s triggered by %s!%s@%s at %s\n",
00401                         ak->nick, ak->user, ak->host, tmpnick->nick,
00402                         tmpnick->user, tmpnick->host, ctime(&CTime));
00403 #ifdef AKILLMAILTO
00404                 kline_enforce_buf += buf;
00405                 kline_email_nitems++;
00406 #endif
00407 
00408 #ifdef OPSMAILTO
00409                 ops_enforce_buf += buf;
00410                 ops_email_nitems++;
00411 #endif
00412 
00413 /* XXX: Where did this remUser come from ? Note to check rev 1.69<->1.70 */
00414                 remUser(inick, 1);
00415 
00416                 if (strcmp(ak->nick, "*")) {
00417                     addGhost(inick);
00418                     timer(30, delTimedGhost, strdup(inick));
00419                 }
00420                 continue;
00421             }
00422         }
00423 }
00424 
00449 int addakill(long length, char *mask, char *by, char type, char *reason)
00450 {
00451     struct akill *ak;
00452     char *akmask;
00453     int i, j;
00454     char temp[16];
00455 
00456     ak = (struct akill *)oalloc(sizeof(struct akill));
00457     akmask = strdup(mask);
00458 
00459     ak->nick = akmask;
00460 
00461     j = strlen(akmask);
00462     for (i = 0; i < j; i++) {
00463         if (akmask[i] == '!') {
00464             akmask[i] = 0;
00465             ak->user = &(akmask[i + 1]);
00466         }
00467         if (akmask[i] == '@') {
00468             akmask[i] = 0;
00469             ak->host = &(akmask[i + 1]);
00470         }
00471     }
00472     if (firstBanItem)
00473         firstBanItem->prev = ak;
00474     ak->next = firstBanItem;
00475     ak->prev = NULL;
00476     firstBanItem = ak;
00477 
00478     strcpy(ak->setby, by);
00479 
00480     ak->set = time(NULL);
00481     if (length == 0)
00482         ak->unset = 0;
00483     else
00484         ak->unset = ak->set + length;
00485 
00486     ak->type = type;
00487     ak->id = ++top_akill_stamp;
00488     strncpyzt(ak->reason, reason, AKREASON_LEN);
00489 
00490     if (length == 0)
00491         strcpy(temp, "forever.");
00492     else
00493         snprintf(temp, 16, "%d hours.", (int)length / 3600);
00494 
00495     sSend(":%s GLOBOPS :%s set %s for %s for %s [%s]", OperServ, by,
00496           aktype_str(type, 0), mask, temp, reason);
00497     if (type == A_AKILL && !strcmp(ak->nick, "*"))
00498         sSend(":%s AKILL %s %s :Autokilled [#%.6x] for %s [%s]", myname,
00499               ak->host, ak->user, ak->id, temp, ak->reason);
00500     else if (type == A_AHURT && !strcmp(ak->nick, "*"))
00501         sSend(":%s AHURT %s %s :Autohurt [#%.6x] for %s [%s]", myname,
00502               ak->host, ak->user, ak->id, temp, ak->reason);
00503 
00504     if (ak->unset)
00505         ak->tid = timer(length, autoremoveakill, strdup(mask));
00506     else
00507         ak->tid = 0;
00508 #if defined(AKILLMAILTO) || defined(OPSMAILTO)
00509     queueakill(mask, ak->setby, temp, reason, ak->set, type, ak->id, 1);
00510 #endif
00511     if (type == A_AHURT || type == A_AKILL)
00512         checkAkillAllUsers(ak);
00513     return 0;
00514 }
00515 
00516 #ifndef AKILLMAILTO
00517 /*void timed_akill_queue(char *)
00518 {
00519     return;
00520 }*/
00521 #endif
00522 
00523 
00536 void queueakill(char *mask, char *setby, char *length, char *reason,
00537                 time_t time, int type, int id, int added)
00538 {
00539     static char buf[8192];
00540 
00541 
00542     if (added) {
00543         sprintf(buf,
00544                 "[#%.6x] %.*s was %.*s by %.*s for %.*s\nReason: %.*s\n"
00545                 "Set At: %.*s\n", id, 255, mask, 255, aktype_str(type, 1),
00546                 NICKLEN, setby, 255, length, 255, reason, 255,
00547                 ctime(&(time)));
00548     } else {
00549         sprintf(buf, "[#%.6x] %.*s removed %.*s %.*s at %.*s\n", id,
00550                 NICKLEN, setby, 255, aktype_str(type, 0),
00551                 NICKLEN + USERLEN + HOSTLEN + 25, mask, 255,
00552                 ctime(&(time)));
00553     }
00554 
00555 #ifdef AKILLMAILTO
00556     kline_email.body.add(buf);
00557     kline_email_nitems++;
00558 #endif
00559 
00560 #ifdef OPSMAILTO
00561     ops_email.body.add(buf);
00562     ops_email_nitems++;
00563 #endif
00564 }
00565 
00566 
00577 const char *aktype_str(int type, int which)
00578 {
00579     int i = 0;
00580     struct akill_type_string_data
00581     {
00582         int type;
00583         char *simple;
00584         char *usimple;
00585         char *action;
00586     } akill_strings[] =
00587     {
00588         {
00589         A_AKILL, "autokill", "Autokill", "autokilled"}
00590         , {
00591         A_IGNORE, "ignore", "Ignore", "ignored"}
00592         , {
00593         A_AHURT, "autohurt", "Autohurt", "autohurt"}
00594         , {
00595         0x0, NULL, NULL, NULL}
00596     };
00597 
00598     for (i = 0; akill_strings[i].simple; i++) {
00599         if (akill_strings[i].type == type)
00600             switch (which) {
00601             default:
00602             case 0:
00603                 return akill_strings[i].simple;
00604             case 1:
00605                 return akill_strings[i].action;
00606             case 2:
00607                 return akill_strings[i].usimple;
00608             }
00609     }
00610 
00611     return ("banitem");
00612 }
00613 
00614 
00619 void timed_akill_queue(char *)
00620 {
00621     char buf1[1024];
00622 
00623 #ifdef AKILLMAILTO
00624     if (
00625         ((kline_email_nitems > 0)
00626          && ((CTime - kline_e_last_time) >= 60 * 60 * 12))
00627         || (kline_email_nitems >= 100)) {
00628         sprintf(buf1, "\"Operator Services - Kline\" <%s@%s>", OperServ,
00629                 NETWORK);
00630 
00631         kline_email.to = AKILLMAILTO;
00632         kline_email.from = buf1;
00633         kline_email.subject = "Queued Kline list";
00634         if (kline_enforce_buf.length() > 0) {
00635             kline_email.body.add("");
00636             kline_email.body.add(kline_enforce_buf.get_string());
00637             kline_enforce_buf.set_string(NULL);
00638         }
00639         kline_email.send();
00640         kline_email.reset();
00641         kline_email_nitems = 0;
00642         kline_e_last_time = time(NULL);
00643         saveKlineQueue();
00644     } else if (!kline_email_nitems)
00645         kline_e_last_time = time(NULL);
00646 #endif
00647 
00648 #if defined(OPSMAILTO)
00649     if ((ops_email_nitems > 0)
00650         && ((CTime - ops_e_last_time) >= 60 * 60 * 24 * 3)) {
00651         sprintf(buf1, "\"Operator Services - Kline\" <%s@%s>", OperServ,
00652                 NETWORK);
00653 
00654         ops_email.to = OPSMAILTO;
00655         ops_email.from = buf1;
00656         ops_email.subject = "Kline log";
00657         if (ops_enforce_buf.length() > 0) {
00658             ops_email.body.add("");
00659             ops_email.body.add(kline_enforce_buf.get_string());
00660             ops_enforce_buf.set_string(NULL);
00661         }
00662         ops_email.send();
00663         ops_email.reset();
00664         ops_email_nitems = 0;
00665         ops_e_last_time = time(NULL);
00666         saveKlineQueue();
00667     } else if (!ops_email_nitems)
00668         ops_e_last_time = time(NULL);
00669 #endif
00670 
00671 #if defined(AKILLMAILTO) || defined(OPSMAILTO)
00672     timer(60 * 60, timed_akill_queue, NULL);
00673 #endif
00674 }
00675 
00682 int removeAkill(char *from, char *mask)
00683 {
00684     int i, j;
00685     struct akill *ak;
00686     char *nick, *user = NULL, *host = NULL, *oldmask;
00687     time_t temp;
00688 
00689     oldmask = strdup(mask);
00690 
00691     j = strlen(mask);
00692     nick = mask;
00693     for (i = 0; i < j; i++) {
00694         if (mask[i] == '!') {
00695             mask[i] = 0;
00696             user = &(mask[i + 1]);
00697         }
00698         if (mask[i] == '@') {
00699             mask[i] = 0;
00700             host = &(mask[i + 1]);
00701         }
00702     }
00703 
00704     for (ak = firstBanItem; ak; ak = ak->next) {
00705         if (!strcmp(host, ak->host) && !strcmp(user, ak->user)
00706             && !strcmp(nick, ak->nick)) {
00707             if (strcasecmp(from, OperServ) && strcasecmp(from, ak->setby)) {
00708                 UserList *fromnl = getNickData(from);
00709                 if (fromnl && !opFlagged(fromnl, OAKILL)) {
00710                     sSend
00711                         (":%s NOTICE %s :Permission denied -- that akill was set by %s.",
00712                          OperServ, from, ak->setby);
00713                     if (oldmask)
00714                         FREE(oldmask);
00715                     return -1;
00716                 }
00717             }
00718             sSend(":%s GLOBOPS :%s is removing %s %s.", OperServ, from,
00719                   aktype_str(ak->type, 0), oldmask);
00720             temp = time(NULL);
00721 
00722 #if defined(AKILLMAILTO) || defined(OPSMAILTO)
00723             queueakill(oldmask, from, NULL, NULL, temp, ak->type, ak->id,
00724                        0);
00725 #endif
00726 
00727             if (ak->prev)
00728                 ak->prev->next = ak->next;
00729             if (ak->next)
00730                 ak->next->prev = ak->prev;
00731             if (ak == firstBanItem)
00732                 firstBanItem = ak->next;
00733             if (ak->type == A_AKILL && !strcmp(nick, "*"))
00734                 sSend(":%s RAKILL %s %s", myname, ak->host, ak->user);
00735             if (ak->type == A_AHURT && !strcmp(nick, "*"))
00736                 sSend(":%s RAHURT %s %s", myname, ak->host, ak->user);
00737             FREE(ak->nick);
00738 /*
00739  * Fun fact:  If OperServ is removing the autokill, the timer is up, and
00740  * it shouldn't be canceled, or two timers will be cancelled...
00741  */
00743             if (strcmp(from, OperServ) == 0);
00744             else {
00745                 sSend(":%s NOTICE %s :%s %s removed", OperServ, from,
00746                       aktype_str(ak->type, 0), oldmask);
00747                 cancel_timer(ak->tid);
00748             }
00749             FREE(ak);
00750             FREE(oldmask);
00751             return 0;
00752         }
00753     }
00754 
00755     if (strcmp(from, OperServ)) {
00756         sSend(":%s NOTICE %s :Autokill/AutoHurt/Ignore %s not found",
00757               OperServ, from, oldmask);
00758     }
00759     FREE(oldmask);
00760     return -1;
00761 }
00762 
00771 int removeAkillType(char *from, char *mask, int type, int restrict)
00772 {
00773     int i, j;
00774     struct akill *ak;
00775     char *nick, *user = NULL, *host = NULL, *oldmask;
00776     time_t temp;
00777 
00778     oldmask = strdup(mask);
00779 
00780     j = strlen(mask);
00781     nick = mask;
00782     for (i = 0; i < j; i++) {
00783         if (mask[i] == '!') {
00784             mask[i] = 0;
00785             user = &(mask[i + 1]);
00786         }
00787         if (mask[i] == '@') {
00788             mask[i] = 0;
00789             host = &(mask[i + 1]);
00790         }
00791     }
00792 
00793     for (ak = firstBanItem; ak; ak = ak->next) {
00794         if (ak->type == type || !type)
00795             if (!strcmp(host, ak->host) && !strcmp(user, ak->user)
00796                 && !strcmp(nick, ak->nick)) {
00797 
00798 
00799                 if (strcasecmp(from, OperServ) && strcasecmp(from, ak->setby)) {
00800                     UserList *fromnl = getNickData(from);
00801                     if (fromnl && !opFlagged(fromnl, OAKILL)) {
00802                         sSend
00803                             (":%s NOTICE %s :Permission denied -- that akill was set by %s.",
00804                              OperServ, from, ak->setby);
00805                         continue;
00806                     }
00807                 }
00808 
00809 
00810                 sSend(":%s GLOBOPS :%s is removing %s %s.", OperServ, from,
00811                       aktype_str(ak->type, 0), oldmask);
00812                 temp = time(NULL);
00813 
00814 #if defined(AKILLMAILTO) || defined(OPSMAILTO)
00815                 queueakill(oldmask, from, NULL, NULL, temp, ak->type,
00816                            ak->id, 0);
00817 #endif
00818                 if (ak->prev)
00819                     ak->prev->next = ak->next;
00820                 if (ak->next)
00821                     ak->next->prev = ak->prev;
00822                 if (ak == firstBanItem)
00823                     firstBanItem = ak->next;
00824                 if (ak->type == A_AKILL && !strcmp(nick, "*"))
00825                     sSend(":%s RAKILL %s %s", myname, ak->host, ak->user);
00826                 if (ak->type == A_AHURT && !strcmp(nick, "*"))
00827                     sSend(":%s RAHURT %s %s", myname, ak->host, ak->user);
00828 
00834                 if (strcmp(from, OperServ)) {
00835                     sSend(":%s NOTICE %s :%s %s removed", OperServ, from,
00836                           aktype_str(ak->type, 0), oldmask);
00837                     cancel_timer(ak->tid);  /* If OperServ is removing the kill, timer is up&shouldn't be canceled */
00838                 }
00839                 FREE(ak);
00840                 FREE(oldmask);
00841                 return 0;
00842             }
00843     }
00844     if (strcmp(from, OperServ)) {
00845         sSend(":%s NOTICE %s :%s %s not found", OperServ, from,
00846               aktype_str(type, 2), oldmask);
00847     }
00848     return -1;
00849 }
00850 
00857 void autoremoveakill(char *mask)
00858 {
00859     removeAkill(OperServ, mask);
00860     FREE(mask);
00861 }
00862 
00867 void saveakills()
00868 {
00869     FILE *aksave;
00870     struct akill *ak;
00871 
00872     saveKlineQueue();
00873 
00874     aksave = fopen("operserv/akill.db", "w");
00875 
00876     for (ak = firstBanItem; ak != NULL; ak = ak->next) {
00877         fputs("-\n", aksave);
00878         fprintf(aksave, "#ID %d\n", ak->id);
00879         fputs(ak->nick, aksave);
00880         fputs("\n", aksave);
00881         fputs(ak->user, aksave);
00882         fputs("\n", aksave);
00883         fputs(ak->host, aksave);
00884         fputs("\n", aksave);
00885         fprintf(aksave, "%lu %lu\n", (long)ak->set, (long)ak->unset);
00886         fputs(ak->setby, aksave);
00887         fputs("\n", aksave);
00888         fputs(ak->reason, aksave);
00889         fputs("\n", aksave);
00890         fprintf(aksave, "%d\n", ak->type);
00891     }
00892     fclose(aksave);
00893     return;
00894 }
00895 
00902 void loadKlineQueue()
00903 {
00904     FILE *fp = fopen("operserv/kline_queue.db", "r");
00905     char buf[1024];
00906     EmailMessage *email;
00907     int lines = 0;
00908 
00909     if (!fp)
00910         return;
00911     if (fgets(buf, 255, fp)) {
00912         kline_e_last_time = 0;
00913         ops_e_last_time = 0;
00914         sscanf(buf, "%ld:%ld", &kline_e_last_time, &ops_e_last_time);
00915     } else {
00916         fclose(fp);
00917         return;
00918     }
00919 
00920     email = &kline_email;
00921 
00922     while (fgets(buf, 255, fp)) {
00923         if (buf[0] && buf[0] != '\n' && strchr(buf, '\n')
00924                     && buf[1] == '\n') {
00925             buf[strlen(buf) - 1] = 0;
00926         }
00927 
00928         if (*buf == 'F')
00929             email->from.add(buf + 1);
00930         else if (*buf == 'T') {
00931             email->to.add(buf + 1);
00932         } else if (*buf == 'S')
00933             email->subject.add(buf + 1);
00934         else if (*buf == 'B') {
00935             email->body.add(buf + 1);
00936             lines++;
00937         } else if (*buf == 'E') {
00938             if (lines) {
00939                 if (email == &kline_email)
00940                     kline_email_nitems++;
00941                 else if (email == &ops_email)
00942                     ops_email_nitems++;
00943             }
00944 
00945             if (email == &ops_email)
00946                 break;
00947             email = &ops_email;
00948             lines = 0;
00949         }
00950     }
00951 
00952     while (fgets(buf, 255, fp)) {
00953         if (buf[0] && buf[0] != '\n' && strchr(buf, '\n')
00954                     && buf[1] == '\n') {
00955             buf[strlen(buf) - 1] = 0;
00956         }
00957 
00958         if (*buf == 'X')
00959             kline_enforce_buf.add(buf + 1);
00960         else if (*buf == 'O')
00961             ops_enforce_buf.add(buf + 1);
00962         }
00963 
00964     if (fclose(fp) < 0) {
00965         perror("fclose");
00966     }
00967 }
00968 
00976 void parseFprint(FILE * fp, char pre, const char *str)
00977 {
00978     char buf[8192], *s, *a;
00979 
00980     if (!fp || !str)
00981         return;
00982     strncpyzt(buf, str, sizeof(buf));
00983     buf[sizeof(buf) - 1] = '\0';
00984 
00985     for (s = a = buf; *s; s++) {
00986         if (*s == '\n') {
00987             *s = '\0';
00988             fprintf(fp, "%c%s\n", pre, a);
00989             *s = '\n';
00990             a = s + 1;
00991         }
00992     }
00993     if (a[0] && a[0] != '\n');
00994     fprintf(fp, "%c%s\n", pre, a);
00995 }
00996 
01000 void saveKlineQueue()
01001 {
01002     FILE *fp = fopen("operserv/kline_queue.db", "w");
01003     EmailMessage *email;
01004     int i = 0;
01005 
01006     if (!fp)
01007         return;
01008 
01009     fprintf(fp, "%ld:%ld\n", kline_e_last_time, ops_e_last_time);
01010 
01011     for(i = 0; i < 2; i++)
01012     {
01013         switch(i) {
01014             case 1: email = &ops_email; break;
01015             default: email = &kline_email; break;
01016         }
01017 
01018         parseFprint(fp, 'F', email->from.get_string());
01019         parseFprint(fp, 'T', email->to.get_string());
01020         parseFprint(fp, 'S', email->subject.get_string());
01021         parseFprint(fp, 'B', email->body.get_string());
01022         fprintf(fp, "E\n");
01023     }
01024 
01025     if (kline_enforce_buf.length() > 0)
01026         parseFprint(fp, 'X', kline_enforce_buf.get_string());
01027 
01028     if (ops_enforce_buf.length() > 0)
01029         parseFprint(fp, 'O', ops_enforce_buf.get_string());
01030 
01031     if (fclose(fp) < 0) {
01032         perror("fclose");
01033     }
01034 }
01035 
01039 void loadakills()
01040 {
01041     FILE *akload;
01042     struct akill *ak;
01043     char buffer[256], mask[NICKLEN + USERLEN + HOSTLEN + 2], temp[16];
01044     int i = 0, t, expired = 0, count = 0, start;
01045     long length;
01046 
01047     start = time(NULL);
01048 
01049     loadKlineQueue();
01050 
01051     akload = fopen("operserv/akill.db", "r");
01052 
01053     if (akload == NULL) {
01054         sSend(":%s GLOBOPS :Autokill EXPIRE(0/0) in %ld seconds", OperServ,
01055               (long)(time(NULL) - start));
01056         return;
01057     }
01058 
01059     while (sfgets(buffer, 256, akload)) {
01060 /*
01061  * Check for sync 
01062  */
01063         ++i;
01064 
01065         if (strcmp(buffer, "-") != 0) {
01066             sSend("%s GLOBOPS :Sync error in akill.db near line %d",
01067                   OperServ, i);
01068             fprintf(corelog, "Sync error in akill.db near line %d", i);
01069             return;
01070         }
01071         ak = (struct akill *)oalloc(sizeof(struct akill));
01072 
01073         sfgets(buffer, 256, akload);
01074         ++i;
01075 
01076         if (*buffer != '#') {
01077             ak->nick = strdup(buffer);
01078             ak->id = ++top_akill_stamp;
01079         } else {
01080             if (!strncmp(buffer, "#ID ", 4)) {
01081                 ak->id = atoi(buffer + 4);
01082                 if (((unsigned)ak->id) > top_akill_stamp)
01083                     top_akill_stamp = ak->id;
01084             } else
01085                 ak->id = ++top_akill_stamp;
01086             sfgets(buffer, 256, akload);
01087             ++i;
01088             ak->nick = strdup(buffer);
01089         }
01090         sfgets(buffer, 256, akload);
01091         ++i;
01092         ak->user = strdup(buffer);
01093         sfgets(buffer, 256, akload);
01094         ++i;
01095         ak->host = strdup(buffer);
01096         fscanf(akload, "%lu %lu\n", (long *)&(ak->set),
01097                (long *)&(ak->unset));
01098         ++i;
01099         sfgets(ak->setby, NICKLEN, akload);
01100         ++i;
01101         sfgets(buffer, 255, akload);
01102         ++i;
01103         strncpyzt(ak->reason, buffer, AKREASON_LEN);
01104         fscanf(akload, "%d\n", &t);
01105         ++i;
01106 
01107         ak->type = t;
01108         ak->tid = 0;
01109 
01110         strcpy(mask, ak->nick);
01111         strcat(mask, "!");
01112         strcat(mask, ak->user);
01113         strcat(mask, "@");
01114         strcat(mask, ak->host);
01115 
01116         count++;
01117         length = ak->unset - ak->set;
01118 
01119         if (ak->unset)
01120             sprintf(temp, "%d hours", (int)(length / 3600));
01121         else
01122             strcpy(temp, "forever");
01123 
01124         if ((start < ak->unset) || (ak->unset == 0)) {
01125             if (ak->unset)
01126                 ak->tid =
01127                     timer((ak->unset - start), autoremoveakill,
01128                           strdup(mask));
01129             if (strcmp(ak->nick, "*") == 0) {
01130                 if (ak->type == A_AKILL && !strcmp(ak->nick, "*"))
01131                     sSend(":%s AKILL %s %s :Autokilled by %s for %s [%s]",
01132                           myname, ak->host, ak->user, ak->setby, temp,
01133                           ak->reason);
01134                 if (ak->type == A_AHURT && !strcmp(ak->nick, "*"))
01135                     sSend(":%s AHURT %s %s :AutoHurt for %s [%s]", myname,
01136                           ak->host, ak->user, temp, ak->reason);
01137             }
01138             ak->next = firstBanItem;
01139             ak->prev = NULL;
01140             if (ak->next)
01141                 ak->next->prev = ak;
01142             firstBanItem = ak;
01143         } else {
01144             /*
01145              * It's expired! 
01146              */
01147             if (ak->type == A_AKILL)
01148                 sSend(":%s RAKILL %s %s", myname, ak->host, ak->user);
01149             if (ak->type == A_AHURT)
01150                 sSend(":%s RAHURT %s %s", myname, ak->host, ak->user);
01151             expired++;
01152             FREE(ak->nick);
01153             FREE(ak->user);
01154             FREE(ak->host);
01155             FREE(ak);
01156         }
01157     }
01158     sSend(":%s GLOBOPS :Autokill EXPIRE(%d/%d) in %ld seconds", OperServ,
01159           expired, count, (long)(time(NULL) - start));
01160     if (top_akill_stamp)
01161         top_akill_stamp += 10;
01162 }

Generated at Sat Oct 25 20:56:06 2003 for Services using Doxygen.
Services Copyr. 1996-2001 Chip Norkus, Max Byrd, Greg Poma, Michael Graff, James Hess, Dafydd James. All rights reserved See LICENSE for licensing information.