os_akill.c

Go to the documentation of this file.
00001 /* OperServ core functions
00002  *
00003  * (C) 2003-2007 Anope Team
00004  * Contact us at info@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church. 
00010  * 
00011  * $Id: os_akill.c 1301 2007-09-06 00:16:31Z drstein $
00012  *
00013  */
00014 /*************************************************************************/
00015 
00016 #include "module.h"
00017 
00018 int do_akill(User * u);
00019 int akill_view_callback(SList * slist, int number, void *item,
00020                         va_list args);
00021 int akill_view(int number, Akill * ak, User * u, int *sent_header);
00022 int akill_list_callback(SList * slist, int number, void *item,
00023                         va_list args);
00024 int akill_list(int number, Akill * ak, User * u, int *sent_header);
00025 void myOperServHelp(User * u);
00026 
00033 int AnopeInit(int argc, char **argv)
00034 {
00035     Command *c;
00036 
00037     moduleAddAuthor("Anope");
00038     moduleAddVersion
00039         ("$Id: os_akill.c 1301 2007-09-06 00:16:31Z drstein $");
00040     moduleSetType(CORE);
00041     c = createCommand("AKILL", do_akill, is_services_oper, OPER_HELP_AKILL,
00042                       -1, -1, -1, -1);
00043     moduleAddCommand(OPERSERV, c, MOD_UNIQUE);
00044 
00045     moduleSetOperHelp(myOperServHelp);
00046 
00047     return MOD_CONT;
00048 }
00049 
00053 void AnopeFini(void)
00054 {
00055 
00056 }
00057 
00058 
00059 
00064 void myOperServHelp(User * u)
00065 {
00066     if (is_services_oper(u)) {
00067         notice_lang(s_OperServ, u, OPER_HELP_CMD_AKILL);
00068     }
00069 }
00070 
00076 /* Manage the AKILL list. */
00077 
00078 int do_akill(User * u)
00079 {
00080     char *cmd = strtok(NULL, " ");
00081     char breason[BUFSIZE];
00082 
00083     if (!cmd)
00084         cmd = "";
00085 
00086     if (!stricmp(cmd, "ADD")) {
00087         int deleted = 0;
00088         char *expiry, *mask, *reason;
00089         time_t expires;
00090 
00091         mask = strtok(NULL, " ");
00092         if (mask && *mask == '+') {
00093             expiry = mask;
00094             mask = strtok(NULL, " ");
00095         } else {
00096             expiry = NULL;
00097         }
00098 
00099         expires = expiry ? dotime(expiry) : AutokillExpiry;
00100         /* If the expiry given does not contain a final letter, it's in days,
00101          * said the doc. Ah well.
00102          */
00103         if (expiry && isdigit(expiry[strlen(expiry) - 1]))
00104             expires *= 86400;
00105         /* Do not allow less than a minute expiry time */
00106         if (expires != 0 && expires < 60) {
00107             notice_lang(s_OperServ, u, BAD_EXPIRY_TIME);
00108             return MOD_CONT;
00109         } else if (expires > 0) {
00110             expires += time(NULL);
00111         }
00112 
00113         if (mask && (reason = strtok(NULL, ""))) {
00114             /* We first do some sanity check on the proposed mask. */
00115             if (strchr(mask, '!')) {
00116                 notice_lang(s_OperServ, u, OPER_AKILL_NO_NICK);
00117                 return MOD_CONT;
00118             }
00119 
00120             if (!strchr(mask, '@')) {
00121                 notice_lang(s_OperServ, u, BAD_USERHOST_MASK);
00122                 return MOD_CONT;
00123             }
00124 
00125             if (mask && strspn(mask, "~@.*?") == strlen(mask)) {
00126                 notice_lang(s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask);
00127                 return MOD_CONT;
00128             }
00129 
00135             if (AddAkiller) {
00136                 snprintf(breason, sizeof(breason), "[%s] %s", u->nick,
00137                          reason);
00138                 reason = sstrdup(breason);
00139             }
00140 
00141             deleted = add_akill(u, mask, u->nick, expires, reason);
00142             if (deleted < 0) {
00143                 if (AddAkiller) {
00144                     free(reason);
00145                 }
00146                 return MOD_CONT;
00147             } else if (deleted) {
00148                 notice_lang(s_OperServ, u, OPER_AKILL_DELETED_SEVERAL,
00149                             deleted);
00150             }
00151             notice_lang(s_OperServ, u, OPER_AKILL_ADDED, mask);
00152 
00153             if (WallOSAkill) {
00154                 char buf[128];
00155 
00156                 if (!expires) {
00157                     strcpy(buf, "does not expire");
00158                 } else {
00159                     int wall_expiry = expires - time(NULL);
00160                     char *s = NULL;
00161 
00162                     if (wall_expiry >= 86400) {
00163                         wall_expiry /= 86400;
00164                         s = "day";
00165                     } else if (wall_expiry >= 3600) {
00166                         wall_expiry /= 3600;
00167                         s = "hour";
00168                     } else if (wall_expiry >= 60) {
00169                         wall_expiry /= 60;
00170                         s = "minute";
00171                     }
00172 
00173                     snprintf(buf, sizeof(buf), "expires in %d %s%s",
00174                              wall_expiry, s,
00175                              (wall_expiry == 1) ? "" : "s");
00176                 }
00177 
00178                 anope_cmd_global(s_OperServ,
00179                                  "%s added an AKILL for %s (%s) (%s)",
00180                                  u->nick, mask, reason, buf);
00181             }
00182 
00183             if (readonly) {
00184                 notice_lang(s_OperServ, u, READ_ONLY_MODE);
00185             }
00186             if (AddAkiller) {
00187                 free(reason);
00188             }
00189         } else {
00190             syntax_error(s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX);
00191         }
00192 
00193     } else if (!stricmp(cmd, "DEL")) {
00194 
00195         char *mask;
00196         int res = 0;
00197 
00198         mask = strtok(NULL, " ");
00199 
00200         if (!mask) {
00201             syntax_error(s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX);
00202             return MOD_CONT;
00203         }
00204 
00205         if (akills.count == 0) {
00206             notice_lang(s_OperServ, u, OPER_AKILL_LIST_EMPTY);
00207             return MOD_CONT;
00208         }
00209 
00210         if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
00211             /* Deleting a range */
00212             res = slist_delete_range(&akills, mask, NULL);
00213             if (res == 0) {
00214                 notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
00215                 return MOD_CONT;
00216             } else if (res == 1) {
00217                 notice_lang(s_OperServ, u, OPER_AKILL_DELETED_ONE);
00218             } else {
00219                 notice_lang(s_OperServ, u, OPER_AKILL_DELETED_SEVERAL,
00220                             res);
00221             }
00222         } else {
00223             if ((res = slist_indexof(&akills, mask)) == -1) {
00224                 notice_lang(s_OperServ, u, OPER_AKILL_NOT_FOUND, mask);
00225                 return MOD_CONT;
00226             }
00227 
00228             slist_delete(&akills, res);
00229             notice_lang(s_OperServ, u, OPER_AKILL_DELETED, mask);
00230         }
00231 
00232         if (readonly)
00233             notice_lang(s_OperServ, u, READ_ONLY_MODE);
00234 
00235     } else if (!stricmp(cmd, "LIST")) {
00236         char *mask;
00237         int res, sent_header = 0;
00238 
00239         if (akills.count == 0) {
00240             notice_lang(s_OperServ, u, OPER_AKILL_LIST_EMPTY);
00241             return MOD_CONT;
00242         }
00243 
00244         mask = strtok(NULL, " ");
00245 
00246         if (!mask || (isdigit(*mask)
00247                       && strspn(mask, "1234567890,-") == strlen(mask))) {
00248             res =
00249                 slist_enum(&akills, mask, &akill_list_callback, u,
00250                            &sent_header);
00251             if (res == 0) {
00252                 notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
00253                 return MOD_CONT;
00254             } else {
00255                 notice_lang(s_OperServ, u, END_OF_ANY_LIST, "Akill");
00256             }
00257         } else {
00258             int i;
00259             char amask[BUFSIZE];
00260 
00261             for (i = 0; i < akills.count; i++) {
00262                 snprintf(amask, sizeof(amask), "%s@%s",
00263                          ((Akill *) akills.list[i])->user,
00264                          ((Akill *) akills.list[i])->host);
00265                 if (!stricmp(mask, amask)
00266                     || match_wild_nocase(mask, amask))
00267                     akill_list(i + 1, akills.list[i], u, &sent_header);
00268             }
00269 
00270             if (!sent_header)
00271                 notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
00272             else {
00273                 notice_lang(s_OperServ, u, END_OF_ANY_LIST, "Akill");
00274             }
00275         }
00276     } else if (!stricmp(cmd, "VIEW")) {
00277         char *mask;
00278         int res, sent_header = 0;
00279 
00280         if (akills.count == 0) {
00281             notice_lang(s_OperServ, u, OPER_AKILL_LIST_EMPTY);
00282             return MOD_CONT;
00283         }
00284 
00285         mask = strtok(NULL, " ");
00286 
00287         if (!mask || (isdigit(*mask)
00288                       && strspn(mask, "1234567890,-") == strlen(mask))) {
00289             res =
00290                 slist_enum(&akills, mask, &akill_view_callback, u,
00291                            &sent_header);
00292             if (res == 0) {
00293                 notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
00294                 return MOD_CONT;
00295             }
00296         } else {
00297             int i;
00298             char amask[BUFSIZE];
00299 
00300             for (i = 0; i < akills.count; i++) {
00301                 snprintf(amask, sizeof(amask), "%s@%s",
00302                          ((Akill *) akills.list[i])->user,
00303                          ((Akill *) akills.list[i])->host);
00304                 if (!stricmp(mask, amask)
00305                     || match_wild_nocase(mask, amask))
00306                     akill_view(i + 1, akills.list[i], u, &sent_header);
00307             }
00308 
00309             if (!sent_header)
00310                 notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
00311         }
00312     } else if (!stricmp(cmd, "CLEAR")) {
00313         slist_clear(&akills, 1);
00314         notice_lang(s_OperServ, u, OPER_AKILL_CLEAR);
00315     } else {
00316         syntax_error(s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX);
00317     }
00318     return MOD_CONT;
00319 }
00320 
00321 int akill_view(int number, Akill * ak, User * u, int *sent_header)
00322 {
00323     char mask[BUFSIZE];
00324     char timebuf[32], expirebuf[256];
00325     struct tm tm;
00326 
00327     if (!ak)
00328         return 0;
00329 
00330     if (!*sent_header) {
00331         notice_lang(s_OperServ, u, OPER_AKILL_VIEW_HEADER);
00332         *sent_header = 1;
00333     }
00334 
00335     snprintf(mask, sizeof(mask), "%s@%s", ak->user, ak->host);
00336     tm = *localtime(&ak->seton);
00337     strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT,
00338                   &tm);
00339     expire_left(u->na, expirebuf, sizeof(expirebuf), ak->expires);
00340     notice_lang(s_OperServ, u, OPER_AKILL_VIEW_FORMAT, number, mask,
00341                 ak->by, timebuf, expirebuf, ak->reason);
00342 
00343     return 1;
00344 }
00345 
00346 /* Lists an AKILL entry, prefixing it with the header if needed */
00347 
00348 int akill_list_callback(SList * slist, int number, void *item,
00349                         va_list args)
00350 {
00351     User *u = va_arg(args, User *);
00352     int *sent_header = va_arg(args, int *);
00353 
00354     return akill_list(number, item, u, sent_header);
00355 }
00356 
00357 /* Callback for enumeration purposes */
00358 
00359 int akill_view_callback(SList * slist, int number, void *item,
00360                         va_list args)
00361 {
00362     User *u = va_arg(args, User *);
00363     int *sent_header = va_arg(args, int *);
00364 
00365     return akill_view(number, item, u, sent_header);
00366 }
00367 
00368 /* Lists an AKILL entry, prefixing it with the header if needed */
00369 int akill_list(int number, Akill * ak, User * u, int *sent_header)
00370 {
00371     char mask[BUFSIZE];
00372 
00373     if (!ak)
00374         return 0;
00375 
00376     if (!*sent_header) {
00377         notice_lang(s_OperServ, u, OPER_AKILL_LIST_HEADER);
00378         *sent_header = 1;
00379     }
00380 
00381     snprintf(mask, sizeof(mask), "%s@%s", ak->user, ak->host);
00382     notice_lang(s_OperServ, u, OPER_AKILL_LIST_FORMAT, number, mask,
00383                 ak->reason);
00384 
00385     return 1;
00386 }

Generated on Sun Dec 30 09:26:48 2007 for Anope by  doxygen 1.5.1-20070107