00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "services.h"
00047 #include "nickserv.h"
00048 #include "chanserv.h"
00049 #include "operserv.h"
00050 #include "infoserv.h"
00051 #include "gameserv.h"
00052 #include "clone.h"
00053 #include "hash.h"
00054 #include "log.h"
00055 #include "macro.h"
00056 #include "interp.h"
00057 #include "hash/md5pw.h"
00058
00059
00060
00061 void listCloneAlerts(UserList *);
00062
00063 u_long counterOldCSFmt = 0;
00064 static UserList *os_user_override = (UserList *)0;
00065
00067 interp::service_cmd_t operserv_commands[] = {
00068
00069 { "help", os_help, 0, LOG_NO },
00070 { "autokill", os_akill, 0, LOG_NO },
00071 { "akill", os_akill, 0, LOG_NO },
00072 { "tempakill",os_tempakill,0, LOG_DB },
00073 #ifdef ENABLE_AHURT
00074 { "ahurt", os_akill, 0, LOG_NO },
00075 { "autohurt", os_akill, 0, LOG_NO },
00076 #endif
00077 { "clonerule",os_clonerule,0, LOG_DB },
00078 { "ignore", os_akill, 0, LOG_NO },
00079 { "mode", os_mode, 0, LOG_OK },
00080 { "raw", os_raw, ORAW, LOG_OK },
00081 { "shutdown", os_shutdown, OROOT, LOG_OK },
00082 { "reset", os_reset, OROOT, LOG_OK },
00083 { "rehash", os_reset, OROOT, LOG_OK },
00084 { "jupe", os_jupe, OJUPE, LOG_OK },
00085 { "uptime", os_uptime, 0, LOG_NO },
00086 { "timers", os_timers, 1, LOG_NO },
00087 { "sync", os_sync, OROOT, LOG_OK },
00088 { "trigger", os_trigger, 0, LOG_OK },
00089 { "match", os_match, 0, LOG_NO },
00090 { "cloneset", os_cloneset, 0, LOG_OK },
00091 #ifndef _DOXYGEN
00092 { MSG_REMSRA, os_remsra, 0, LOG_NO },
00093 #endif
00094 { "setop", os_setop, 0, LOG_NO },
00095 { "grpop", os_grpop , 0, LOG_DB },
00096 { "override", os_override, 0, LOG_NO },
00097 { "heal", os_heal, 0, LOG_OK },
00098 { "strike", os_strike, 0, LOG_ALWAYS },
00099 { "nixghost", os_nixghost, 0, LOG_ALWAYS },
00100 { NULL, NULL, 0, LOG_NO }
00101 };
00102
00104 const char *cloneset_bits[] = {
00105 "KILL", "IGNORE", "", "OK", NULL
00106 };
00107
00108
00109
00110
00112 #define SETCLR(var, flag, onoff) do { \
00113 if (onoff) \
00114 (var) |= (flag); \
00115 else \
00116 (var) &= ~(flag); \
00117 } while (0)
00118
00128 void sendToOperServ(UserList * nick, char **args, int numargs)
00129 {
00130 char *from = nick->nick;
00131 interp::parser * cmd;
00132
00133 if (numargs < 1) {
00134 sSend(":%s NOTICE %s :huh?", OperServ, from);
00135 return;
00136 }
00137
00138 if (!isOper(nick)) {
00139 sSend(":%s NOTICE %s "
00140 ":You must be an IRC Operator to use this service.",
00141 OperServ, from);
00142 return;
00143 }
00144
00145
00146 cmd =
00147 new interp::parser(OperServ, getOpFlags(nick), operserv_commands,
00148 args[0]);
00149 if (!cmd)
00150 return;
00151 switch (cmd->run(nick, args, numargs)) {
00152 default:
00153 break;
00154 case RET_FAIL:
00155 sSend(":%s NOTICE %s :Unknown command %s.\r\n"
00156 ":%s NOTICE %s :Please try /msg %s HELP", OperServ, from,
00157 args[0], OperServ, from, OperServ);
00158 break;
00159 }
00160 delete cmd;
00161 return;
00162 }
00163
00164
00165
00167 int userOverriding(UserList * nick)
00168 {
00169 return (os_user_override == nick);
00170 }
00171
00172
00173
00174
00180 OCMD(os_help)
00181 {
00182 help(nick->nick, OperServ, args, numargs);
00183 return RET_OK;
00184 }
00185
00186
00187
00188
00194 OCMD(os_setop)
00195 {
00196 sendToNickServ(nick, args, numargs);
00197 return RET_OK;
00198 }
00199
00200
00240 OCMD(os_akill)
00241 {
00242 int i, t, count, akill_type, has_prim = 0;
00243 interp::services_cmd_id log_type = OS_AKILL;
00244 char akreason[IRCBUF];
00245 const char *listProper, *p;
00246 flag_t permPrim, perm2;
00247 char *from = nick->nick;
00248 # if AKREASON_LEN >= IRCBUF
00249 # error AKREASON_LEN cannot be >= IRCBUF!
00250 *;
00251 # endif
00252
00253 permPrim = perm2 = OROOT;
00254
00255 if (numargs < 1)
00256 return RET_EFAULT;
00257
00258
00259
00260
00261
00262
00263 if (!str_cmp(args[0], "akill") || !str_cmp(args[0], "autokill"))
00264 {
00265 permPrim = OAKILL;
00266 perm2 = ORAKILL;
00267 akill_type = A_AKILL;
00268 log_type = OS_AKILL;
00269 }
00270 else if (!str_cmp(args[0], "ahurt") || !str_cmp(args[0], "autohurt"))
00271 {
00272 permPrim = OAHURT;
00273 akill_type = A_AHURT;
00274 log_type = OS_AHURT;
00275 }
00276 else if (!str_cmp(args[0], "ignore"))
00277 {
00278 permPrim = OIGNORE;
00279 akill_type = A_IGNORE;
00280 log_type = OS_IGNORE;
00281 }
00282 else {
00283 sSend(":%s NOTICE %s :Internal Error (args[0] = %s)",
00284 OperServ, from, args[0]);
00285 sSend(":%s GLOBOPS :os_akill: Internal Error (args[0] = %s)",
00286 OperServ, args[0]);
00287 return RET_FAIL;
00288 }
00289
00290
00291
00292 listProper = aktype_str(akill_type, 0);
00293
00294
00295
00296
00297 if ((numargs < 2) || (!str_cmp(args[1], "list"))) {
00298 if (!opFlagged(nick, OVERRIDE))
00299 listAkills(from, akill_type);
00300 else
00301 listAkills(from, 0);
00302 return RET_OK;
00303 }
00304
00305
00306
00307
00308 if (!isServop(nick) && !isRoot(nick) && !opFlagged(nick, permPrim)
00309 && !opFlagged(nick, perm2)) {
00310 sSend(":%s NOTICE %s :Permission denied.", OperServ, from);
00311
00312 return RET_NOPERM;
00313 }
00314 else if (isRoot(nick) || isServop(nick) || opFlagged(nick, permPrim))
00315 {
00316 has_prim = 1;
00317 }
00318
00319
00320
00321
00322 if (args[1][0] == '-' || !strcasecmp(args[1], "del")) {
00323 if (args[1][0] != '-' || args[1][1] == '\0')
00324 {
00325 if ((numargs < 3) || !strchr(args[2], '!')
00326 || !strchr(args[2], '@'))
00327 {
00328 PutError(OperServ, nick, ERR_AKILLSYNTAX_1ARG, args[0], 0, 0);
00329 PutReply(OperServ, nick, RPL_AKILLHELP_2ARG, OperServ, listProper, 0);
00330 return RET_SYNTAX;
00331 }
00332 if (!removeAkillType(from, args[2], akill_type,
00333 has_prim == 0 ? 1 : 0))
00334 operlog->log(nick, log_type, args[2], LOGF_OFF);
00335 }
00336 else {
00337 if ((numargs != 2) || !strchr(args[1], '!')
00338 || !strchr(args[1], '@'))
00339 {
00340 PutError(OperServ, nick, ERR_AKILLSYNTAX_1ARG, args[0], 0, 0);
00341 PutReply(OperServ, nick, RPL_AKILLHELP_2ARG, OperServ, listProper, 0);
00342 return RET_SYNTAX;
00343 }
00344
00345
00346
00347 if (!opFlagged(nick, OVERRIDE)) {
00348 if (!removeAkillType(from, args[1]+1, akill_type, has_prim == 0 ? 1 : 0))
00349 operlog->log(nick, log_type, args[1]+1, LOGF_OFF);
00350 }
00351 else {
00352 if (!removeAkill(from, args[1]+1))
00353 operlog->log(nick, log_type, args[1]+1, LOGF_OFF);
00354 }
00355 }
00356
00357 return RET_OK_DB;
00358 }
00359
00360
00361
00362
00363
00364
00365 if ((numargs < 4)
00366 || (strchr(args[2], '!') == NULL)
00367 || (strchr(args[2], '@') == NULL)
00368 || match("*?!?*@?*", args[2])) {
00369
00370 PutError(OperServ, nick, ERR_AKILLSYNTAX_1ARG, args[0], 0, 0);
00371 PutReply(OperServ, nick, RPL_AKILLHELP_2ARG, OperServ, listProper, 0);
00372 return RET_SYNTAX;
00373 }
00374
00375 if (((p = strchr(args[2], '!')) && strchr(p+1, '!')) ||
00376 ((p = strchr(args[2], '%')) && strchr(p+1, '%')) ||
00377 (strchr(args[2], '@') < strchr(args[2], '!')) ||
00378 (((p = strchr(args[2], '@')) && strchr(p+1, '@')))) {
00379 sSend(":%s NOTICE %s :Your specified pattern \2%s\2 does not "
00380 "seem to be well-formed.",
00381 OperServ, from, args[2]);
00382 return RET_FAIL;
00383 }
00384
00385
00386
00387
00388 if (!str_cmp(args[1], "add") || !str_cmp(args[1], "forever"))
00389 t = 0;
00390 else if (*args[1] == '-' || isdigit(*args[1]))
00391 t = atoi(args[1]) * 3600;
00392 else {
00393 PutError(OperServ, nick, ERR_AKILLSYNTAX_1ARG, args[0], 0, 0);
00394 PutReply(OperServ, nick, RPL_AKILLHELP_2ARG, OperServ, listProper, 0);
00395 return RET_SYNTAX;
00396 }
00397
00398 if (!match(args[2], "...!..@...com")
00399 || !match(args[2], "...!..@...net")
00400 || !match(args[2], "...!..@...edu")
00401 || !match(args[2], "...!..@...org")) {
00402 sSend(":%s NOTICE %s :That %s is too broad.", OperServ,
00403 from, listProper);
00404 sSend(":%s GLOBOPS :%s attempts to set %s for %s", OperServ,
00405 from, listProper, args[2]);
00406 return RET_NOPERM;
00407 }
00408 if (!opFlagged(nick, permPrim)) {
00409 char nick[MAXBUF], user[MAXBUF], host[MAXBUF];
00410 if (t > (10800 * 1) || !t)
00411 t = 10800;
00412 sscanf(args[2], "%s!%s@%s", nick, user, host);
00413
00414 if (strlen(args[2]) > 255 || strlen(nick) > 2*NICKLEN ||
00415 strlen(user) > 2*USERLEN || strlen(host) > 2*HOSTLEN
00416 || (strlen(nick)+strlen(user)+strlen(host)) > (NICKLEN+USERLEN+HOSTLEN+2)) {
00417 sSend(":%s NOTICE %s :Pattern too long.", OperServ, from);
00418 return RET_SYNTAX;
00419 }
00420
00421 if ((strchr(host, '*') || strchr(host, '?'))
00422 && (strchr(user, '*') || strchr(user, '?'))
00423 && (strchr(nick, '*') || strchr(nick, '?'))) {
00424 sSend
00425 (":%s NOTICE %s :Your %s access is restricted: you cannot wildcard more than one of the 2 parts of the mask (nick, user, or host).",
00426 OperServ, from, listProper);
00427 return RET_NOPERM;
00428 }
00429 }
00430
00431 strncpyzt(akreason, args[3], AKREASON_LEN);
00432 count = strlen(akreason);
00433
00434 for (i = 4; i < numargs; i++) {
00435 if ((AKREASON_LEN - count) <= 0)
00436 break;
00437 count +=
00438 snprintf(akreason + count, AKREASON_LEN - count, " %s",
00439 args[i]);
00440 }
00441 sSend(":%s NOTICE %s :Adding %s for %s for %d hours [%s]", OperServ,
00442 from, listProper, args[2], t / 3600, akreason);
00443 if (!addakill(t, args[2], from, akill_type, akreason))
00444 operlog->log(nick, log_type, args[2], LOGF_ON,
00445 "%d: %s", t, akreason);
00446 return RET_OK_DB;
00447 }
00448
00449
00450
00458 OCMD(os_tempakill)
00459 {
00460 char *from = nick->nick;
00461 char akreason[IRCBUF];
00462 int i, count;
00463 UserList *user;
00464 char addr[128];
00465
00466 if (numargs < 3) {
00467 sSend(":%s NOTICE %s :Invalid syntax. Try /msg %s help tempakill",
00468 OperServ, from, OperServ);
00469
00470 return RET_SYNTAX;
00471 }
00472
00473 if (strchr(args[1], '*') || strchr(args[1], '?')) {
00474 sSend(":%s NOTICE %s :No wildcards are allowed in a tempakill.",
00475 OperServ, from);
00476
00477 return RET_EFAULT;
00478 }
00479
00480 if (strchr(args[1], '!') || strchr(args[1], '@')) {
00481 sSend
00482 (":%s NOTICE %s :TempAKill should be placed on a nick or hostname, not a full mask.",
00483 OperServ, from);
00484
00485 return RET_EFAULT;
00486 }
00487
00488 if (strchr(args[1], '.'))
00489 snprintf(addr, 128, "*!*@%s", args[1]);
00490 else {
00491 user = getNickData(args[1]);
00492 if (!user) {
00493 sSend(":%s NOTICE %s :No one by that nick is online.",
00494 OperServ, from);
00495
00496 return RET_EFAULT;
00497 }
00498 snprintf(addr, 128, "*!*@%s", user->host);
00499 }
00500
00501 sSend(":%s NOTICE %s :Adding a temp akill for %s for 1 hour.",
00502 OperServ, from, addr);
00503
00504 strncpyzt(akreason, args[2], AKREASON_LEN);
00505 count = strlen(akreason);
00506
00507 for (i = 3; i < numargs; i++) {
00508 if ((AKREASON_LEN - count) <= 0)
00509 break;
00510 count +=
00511 snprintf(akreason + count, AKREASON_LEN - count, "%s%s",
00512 i != 3 ? " " : "", args[i]);
00513 }
00514 addakill(3600, addr, from, A_AKILL, akreason);
00515 return RET_OK_DB;
00516 }
00517
00518
00519
00520
00526 OCMD(os_mode)
00527 {
00528 char *from = nick->nick;
00529 char modeString[IRCBUF];
00530 int on;
00531 int onarg;
00532 int i;
00533 ChanList *tmp;
00534 cBanList *tmpban;
00535 cNickList *tmpnick;
00536
00537
00538 if (numargs < 3) {
00539 sSend(":%s NOTICE %s :You must specify a channel and mode.",
00540 OperServ, from);
00541
00542 return RET_SYNTAX;
00543 }
00544
00545 tmp = getChanData(args[1]);
00546 on = 1;
00547 onarg = 3;
00548
00549 if (!tmp) {
00550 sSend("%s NOTICE %s :No such channel.", OperServ, from);
00551
00552 return RET_EFAULT;
00553 }
00554
00555 for (i = 0; args[2][i]; i++) {
00556 switch (args[2][i]) {
00557 case '+':
00558 on = 1;
00559 break;
00560 case '-':
00561 on = 0;
00562 break;
00563
00564 case 'b':
00565 if (on) {
00566 tmpban = (cBanList *) oalloc(sizeof(cBanList));
00567
00569 if (strlen(args[onarg]) > sizeof(tmpban->ban))
00570 args[onarg][sizeof(tmpban->ban) - 1] = '\0';
00571 strcpy(tmpban->ban, args[onarg]);
00572 addChanBan(tmp, tmpban);
00573 } else {
00574 tmpban = getChanBan(tmp, args[onarg]);
00575 if (tmpban)
00576 delChanBan(tmp, tmpban);
00577 }
00578
00579 onarg++;
00580 break;
00581
00582 case 'i':
00583 SETCLR(tmp->modes, PM_I, on);
00584 break;
00585
00586 case 'l':
00587 SETCLR(tmp->modes, PM_L, on);
00588 if ((on == 0) && tmp->reg)
00589 tmp->reg->limit = 0;
00590 onarg++;
00591 break;
00592
00593 case 'k':
00594 SETCLR(tmp->modes, PM_K, on);
00595 if ((on == 0) && tmp->reg)
00596 tmp->reg->key[0] = 0;
00597 onarg++;
00598 break;
00599
00600 case 'm':
00601 SETCLR(tmp->modes, PM_M, on);
00602 break;
00603
00604 case 'n':
00605 SETCLR(tmp->modes, PM_N, on);
00606 break;
00607
00608 case 'o':
00609 tmpnick = getChanUserData(tmp, getNickData(args[onarg]));
00610 onarg++;
00611 if (tmpnick == NULL)
00612 continue;
00613
00614 SETCLR(tmpnick->op, CHANOP, on);
00615 break;
00616
00617 case 'p':
00618 SETCLR(tmp->modes, PM_P, on);
00619 break;
00620
00621 case 's':
00622 SETCLR(tmp->modes, PM_S, on);
00623 break;
00624
00625 case 't':
00626 SETCLR(tmp->modes, PM_T, on);
00627 break;
00628
00629 case 'v':
00630 tmpnick = getChanUserData(tmp, getNickData(args[onarg]));
00631 onarg++;
00632 if (tmpnick == NULL)
00633 continue;
00634
00635 SETCLR(tmpnick->op, CHANVOICE, on);
00636 break;
00637 }
00638 }
00639
00640 modeString[0] = 0;
00641
00642 for (i = 2; i < onarg; i++) {
00643 strcat(modeString, args[i]);
00644 strcat(modeString, " ");
00645 }
00646
00647 modeString[strlen(modeString) - 1] = 0;
00648 sSend(":%s MODE %s %s", ChanServ, args[1], modeString);
00649
00650 sSend(":%s GLOBOPS :%s MODE %s (%s)", OperServ, from, args[1], modeString);
00651 return RET_OK;
00652 }
00653
00654
00655
00656
00657
00658
00664 OCMD(os_raw)
00665 {
00666 char *from = nick->nick;
00667 char msg[IRCBUF];
00668 int i;
00669
00670 strncpyzt(msg, args[1], sizeof(msg));
00671
00672 for (i = 2; i < numargs; i++) {
00673 strcat(msg, " ");
00674 strcat(msg, args[i]);
00675 }
00676
00677 #ifdef GLOBOPS_ON_RAW
00678 sSend(":%s GLOBOPS :%s used RAW: %s", OperServ, from, msg);
00679 #endif
00680
00681 sSend("%s", msg);
00682 return RET_OK;
00683 }
00684
00685
00686
00687
00688
00694 OCMD(os_shutdown)
00695 {
00696 char *from = nick->nick;
00697 char msg[IRCBUF];
00698 int i;
00699
00700 if (numargs > 1) {
00701 strncpyzt(msg, args[1], sizeof(msg));
00702
00703 for (i = 2; i < numargs; i++) {
00704 strcat(msg, " ");
00705 strcat(msg, args[i]);
00706 }
00707
00708 sSend(":%s WALLOPS :!SHUTDOWN! From %s (%s)", myname, from, msg);
00709 } else
00710 sSend(":%s WALLOPS :!SHUTDOWN! From %s", myname, from);
00711
00712 sshutdown(0);
00713 return RET_OK;
00714 }
00715
00716
00717
00718
00719
00725
00726 OCMD(os_reset)
00727 {
00728 char *from = nick->nick;
00729 char msg[IRCBUF];
00730 int i;
00731
00732 if (numargs > 1) {
00733 strncpyzt(msg, args[1], sizeof(msg));
00734
00735 for (i = 2; i < numargs; i++) {
00736 strcat(msg, " ");
00737 strcat(msg, args[i]);
00738 }
00739
00740 sSend(":%s WALLOPS :Services has been rehashed by %s (%s)", myname,
00741 from, msg);
00742 } else
00743 sSend(":%s WALLOPS :Services has been rehashed by %s", myname,
00744 from);
00745
00746 readConf();
00747 flush_help_cache();
00748 return RET_OK;
00749 }
00750
00751
00752
00753
00754
00755
00756
00761 OCMD(os_jupe)
00762 {
00763 char *from = nick->nick;
00764 time_t now = time(NULL);
00765 char msg[IRCBUF];
00766 int i;
00767
00768 if (numargs < 2) {
00769 sSend(":%s NOTICE %s :Must specify a server to jupe", OperServ,
00770 from);
00771 return RET_SYNTAX;
00772 }
00773
00774 if (numargs > 2) {
00775 strncpyzt(msg, args[2], sizeof(msg));
00776
00777 for (i = 2; i < numargs; i++) {
00778 strcat(msg, " ");
00779 strcat(msg, args[i]);
00780 }
00781
00782 sSend("SERVER %s 2 :Jupitered server [%s:%s] (%s)", args[1], from,
00783 ctime(&now), msg);
00784 sSend(":%s GLOBOPS :Server %s Jupitered by %s at %s (%s)", myname,
00785 args[1], from, ctime(&now), msg);
00786 } else {
00787 sSend("SERVER %s 2 :Jupitered server [%s:%s]", args[1], from,
00788 ctime(&now));
00789 sSend(":%s GLOBOPS :Server %s Jupitered by %s at %s", myname,
00790 args[1], from, ctime(&now));
00791 }
00792 return RET_OK;
00793 }
00794
00795
00796
00803
00804 OCMD(os_uptime)
00805 {
00806 char *from = nick->nick;
00807
00808 time_t now;
00809 int days, hours, mins, seconds;
00810
00811 now = time(NULL);
00812 now -= startup;
00813 days = (now / (24 * 3600));
00814 now %= (24 * 3600);
00815 hours = (now / 3600);
00816 now %= 3600;
00817 mins = (now / 60);
00818 now %= 60;
00819 seconds = now;
00820
00821 sSend(":%s NOTICE %s :Services has been online for:\r\n"
00822 ":%s NOTICE %s :%i days, %i hours, %i minutes, and %i seconds",
00823 OperServ, from, OperServ, from, days, hours, mins, seconds);
00824 sSend(":%s NOTICE %s :(%ld chanserv commands interpreted by hack)",
00825 OperServ, from, counterOldCSFmt);
00826 return RET_OK;
00827 }
00828
00829
00830
00835
00836 OCMD(os_timers)
00837 {
00838 char *from = nick->nick;
00839
00840 dumptimer(from);
00841 return RET_OK;
00842 }
00843
00844
00845
00850
00851 OCMD(os_sync)
00852 {
00853 void writeServicesTotals();
00854
00855 #ifdef GLOBOP_ON_SYNC
00856 char *from = nick->nick;
00857 #endif
00858
00859 #ifdef GLOBOP_ON_SYNC
00860 sSend(":%s GLOBOP :Saving all databases (%s)", OperServ, from);
00861 #endif
00862 strcpy(args[0], "save");
00863 sendToNickServ(nick, args, numargs);
00864 sendToChanServ(nick, args, numargs);
00865 sendToInfoServ(nick, args, numargs);
00866 strcpy(args[0], "savememo");
00867 sendToNickServ(nick, args, numargs);
00868 saveakills();
00869 writeServicesTotals();
00870
00871 return RET_OK_DB;
00872 }
00873
00874
00875
00876
00888 OCMD(os_clonerule)
00889 {
00890 extern void saveTriggerData(void);
00891 char *from = nick->nick, *pCheck;
00892 int c = 0, ct = 0, minargs = 3;
00893 CloneRule *rule, orig;
00894 typedef enum
00895 { CLONEARG_NONE, CLONEARG_LIST, CLONEARG_INFO, CLONEARG_ADD,
00896 CLONEARG_INSERT, CLONEARG_SET, CLONEARG_DEL
00897 }
00898 clonerule_cmds;
00899
00900 if (numargs > 1 && *args[1])
00901 if (!strcasecmp(args[1], "LIST")) {
00902 c = CLONEARG_LIST;
00903 --minargs;
00904 } else if (!strcasecmp(args[1], "INFO")) {
00905 c = CLONEARG_INFO;
00906 } else if (!strcasecmp(args[1], "ADD")) {
00907 c = CLONEARG_ADD;
00908 } else if (!strcasecmp(args[1], "INSERT")) {
00909 c = CLONEARG_INSERT;
00910 } else if (!strcasecmp(args[1], "SET")) {
00911 c = CLONEARG_SET;
00912 ++minargs;
00913 } else if (!strcasecmp(args[1], "DEL")) {
00914 c = CLONEARG_DEL;
00915 }
00916
00917 if (numargs < minargs || c == CLONEARG_NONE) {
00918 sSend(":%s NOTICE %s :Syntax: CLONERULE <list|info|add|del|set>",
00919 OperServ, from);
00920 sSend(":%s NOTICE %s : CLONERULE list [mask]", OperServ,
00921 from);
00922 sSend(":%s NOTICE %s : CLONERULE info <rule#|mask>",
00923 OperServ, from);
00924 if (opFlagged(nick, OOPER | OCLONE) || isRoot(nick)) {
00925 sSend
00926 (":%s NOTICE %s : CLONERULE add <mask> [host trigger]",
00927 OperServ, from);
00928 sSend
00929 (":%s NOTICE %s : CLONERULE insert <mask> [before #]",
00930 OperServ, from);
00931 sSend
00932 (":%s NOTICE %s : CLONERULE set <rule#|mask> FLAGS <flag>",
00933 OperServ, from);
00934 sSend
00935 (":%s NOTICE %s : CLONERULE set <rule#|mask> UTRIGGER <number|0>",
00936 OperServ, from);
00937 sSend
00938 (":%s NOTICE %s : CLONERULE set <rule#|mask> HTRIGGER <number|0>",
00939 OperServ, from);
00940 sSend
00941 (":%s NOTICE %s : CLONERULE set <rule#|mask> WARNMSG <message>",
00942 OperServ, from);
00943 sSend(":%s NOTICE %s : CLONERULE del <rule#|mask>",
00944 OperServ, from);
00945 }
00946 return RET_SYNTAX;
00947 }
00948
00949 if (!opFlagged(nick, OOPER | OCLONE) && !isRoot(nick)
00950 && (c > CLONEARG_INFO)) {
00951 sSend(":%s NOTICE %s :Permission denied.", OperServ, from);
00952 return RET_NOPERM;
00953 }
00954
00955 switch (c) {
00956
00957 case CLONEARG_INFO:
00958 case CLONEARG_LIST:
00959 if (c == CLONEARG_LIST)
00960 sSend(":%s NOTICE %s :***** \2Clone Trigger rules\2 *****",
00961 OperServ, from);
00962 for (rule = first_crule, ct = 1; rule; rule = rule->next, ++ct)
00963
00964
00965 if ((numargs < 3)
00966 || ((isdigit(*args[2]) && atoi(args[2]) == ct)
00967 || !strcasecmp(args[2], rule->mask))) {
00968 if (c == CLONEARG_LIST)
00969 sSend(":%s NOTICE %s :\2%3d\2. %-45s %3d %3d",
00970 OperServ, from, ct, rule->mask, rule->trigger,
00971 rule->utrigger);
00972 else {
00973 sSend
00974 (":%s NOTICE %s :***** \2Persistent clone trigger rule information\2 *****",
00975 OperServ, from);
00976 sSend(":%s NOTICE %s :Mask: \2%s\2", OperServ, from,
00977 rule->mask);
00978 sSend
00979 (":%s NOTICE %s :Username trigger level: \2%3d\2, Host Trigger level: \2%3d\2",
00980 OperServ, from, rule->utrigger, rule->trigger);
00981 sSend(":%s NOTICE %s :Flags: \2%s\2", OperServ, from,
00982 flagstring(rule->flags, cloneset_bits));
00983 sSend(":%s NOTICE %s :Kill Message: \2%s\2", OperServ,
00984 from,
00985 rule->kill_msg ? rule->kill_msg : "(default)");
00986 sSend(":%s NOTICE %s :Warning Message: \2%s\2",
00987 OperServ, from,
00988 rule->warn_msg ? rule->warn_msg : "(none)");
00989 sSend(":%s NOTICE %s :***** \2End of info\2 *****",
00990 OperServ, from);
00991 }
00992 }
00993 if (c == CLONEARG_LIST)
00994 sSend(":%s NOTICE %s :***** \2End of list\2 *****", OperServ,
00995 from);
00996 return RET_OK;
00997 return RET_OK;
00998 case CLONEARG_ADD:
00999 case CLONEARG_INSERT:
01000 if (index(args[2], '!') || !index(args[2], '@')
01001 || !index(args[2], '.')) {
01002 sSend(":%s NOTICE %s :\2%s\2: Invalid mask.", OperServ, from,
01003 args[2]);
01004 return RET_EFAULT;
01005 }
01006 if (GetCrule(args[2])) {
01007 sSend(":%s NOTICE %s :There's already a rule for that mask.",
01008 OperServ, from);
01009 return RET_FAIL;
01010 }
01011 if (!(rule = NewCrule()))
01012 return RET_MEMORY;
01013 orig = *rule;
01014 rule->kill_msg = NULL;
01015 strncpyzt(rule->mask, args[2], sizeof(rule->mask));
01016 rule->trigger = 0;
01017 if (c == CLONEARG_ADD)
01018 if (numargs > 3 && *args[3] && isdigit(*args[3]))
01019 rule->trigger = rule->utrigger = atoi(args[3]);
01020 if (!rule->trigger) {
01021 rule->utrigger = 0;
01022 rule->trigger = 0;
01023 }
01024 rule->flags = DEFCLONEFLAGS;
01025 if (c == CLONEARG_ADD || numargs < 4)
01026 AddCrule(rule, -1);
01027 else {
01028 AddCrule(rule, atoi(args[3]));
01029 sSend(":%s NOTICE %s :--- inserting at point %d", OperServ,
01030 from, atoi(args[3]));
01031 }
01032 sSend(":%s GLOBOPS :%s adding trigger rule for \2%s\2", OperServ,
01033 from, args[2]);
01034 UpdateCrule(orig, rule);
01035 saveTriggerData();
01036 return RET_OK_DB;
01037 case CLONEARG_SET:
01038 if (!(rule = GetCrule(args[2]))) {
01039 sSend(":%s NOTICE %s :\2%s\2: No such trigger default.",
01040 OperServ, from, args[2]);
01041 return RET_NOTARGET;
01042 }
01043 if (numargs < 5) {
01044 sSend(":%s NOTICE %s :Set it to what?", OperServ, from);
01045 return RET_SYNTAX;
01046 }
01047
01048 orig = *rule;
01049
01050 if (!strcasecmp(args[3], "flags")) {
01051 if ((ct = flagbit(args[4], cloneset_bits)) < 0) {
01052 sSend(":%s NOTICE %s :\2%s\2: No such cloneset flag.",
01053 OperServ, from, args[4]);
01054 return RET_EFAULT;
01055 }
01056 sSend(":%s NOTICE %s :\2%s\2 flag %s \2%s\2.", OperServ, from,
01057 args[4],
01058 (rule->flags & (1 << ct)) ? "removed from" : "added to",
01059 rule->mask);
01060 sSend(":%s GLOBOPS :%s %s %s flag on trigger rule for \2%s\2",
01061 OperServ, from,
01062 rule->flags & (1 << ct) ? "cleared" : "set", args[4],
01063 rule->mask);
01064 rule->flags ^= (1 << ct);
01065 UpdateCrule(orig, rule);
01066 } else if (!strcasecmp(args[3], "htrigger")) {
01067 if (!isdigit(*args[4])) {
01068 sSend(":%s NOTICE %s :Invalid host trigger level.",
01069 OperServ, from);
01070 return RET_EFAULT;
01071 }
01072
01073
01074 if (!(pCheck = strchr(args[3], '@')) && atoi(args[4])) {
01075 sSend(":%s NOTICE %s :Cannot set host trigger "
01076 "rewrite unless rule contains a @.",
01077 OperServ, from);
01078 return RET_EFAULT;
01079 }
01080
01081 if (pCheck && (strchr(pCheck, '*') || strchr(pCheck, '?'))
01082 && atoi(args[4])
01083 && !opFlagged(nick, OROOT | OVERRIDE))
01084 {
01085 sSend(":%s NOTICE %s :Cannot set host trigger "
01086 "rewrite with a wildcarded host.",
01087 OperServ, from);
01088 return RET_EFAULT;
01089 }
01090
01091 sSend
01092 (":%s GLOBOPS :%s set host trigger for rule of \2%s\2 %d->%d",
01093 OperServ, from, rule->mask, rule->trigger, atoi(args[4]));
01094 rule->trigger = atoi(args[4]);
01095 sSend(":%s NOTICE %s :Trigger level is now %d.", OperServ,
01096 from, rule->trigger);
01097 UpdateCrule(orig, rule);
01098 } else if (!strcasecmp(args[3], "utrigger")) {
01099 if (!isdigit(*args[4])) {
01100 sSend(":%s NOTICE %s :Invalid user trigger level.",
01101 OperServ, from);
01102 return RET_EFAULT;
01103 }
01104 sSend
01105 (":%s GLOBOPS :%s set user trigger for rule of \2%s\2 %d->%d",
01106 OperServ, from, rule->mask, rule->utrigger,
01107 atoi(args[4]));
01108 rule->utrigger = atoi(args[4]);
01109 sSend(":%s NOTICE %s :User trigger level is now %d.", OperServ,
01110 from, rule->utrigger);
01111 UpdateCrule(orig, rule);
01112 } else if (!strcasecmp(args[3], "kill")
01113 || !strcasecmp(args[3], "killmsg")) {
01114 char tmpbuf[8192] = "";
01115 if (args[4][0] == '\0' || !strcasecmp(args[4], "none")) {
01116 if (rule->kill_msg)
01117 FREE(rule->kill_msg);
01118 rule->kill_msg = NULL;
01119 sSend(":%s NOTICE %s :Kill message cleared.", OperServ,
01120 from);
01121 } else {
01122 parse_str(args, numargs, 4, tmpbuf, IRCBUF);
01123 if (strlen(tmpbuf) > MEMOLEN) {
01124 sSend
01125 (":%s NOTICE %s :Kill message cannot exceed %d characters.",
01126 OperServ, from, MEMOLEN);
01127 return RET_EFAULT;
01128 }
01129 if (rule->kill_msg)
01130 FREE(rule->kill_msg);
01131 rule->kill_msg = strdup(tmpbuf);
01132 if (!rule->kill_msg) {
01133 logDump(corelog,
01134 "Error allocating (%d) bytes of memory for clonerule kill message. (%s!%s@%s)",
01135 strlen(tmpbuf), from, nick->user, nick->host);
01136 sSend
01137 (":%s GLOBOPS :Error allocating (%d) bytes of memory for clonerule kill message. (%s!%s@%s)",
01138 NickServ, strlen(tmpbuf), from, nick->user,
01139 nick->host);
01140 return RET_MEMORY;
01141 }
01142 sSend(":%s NOTICE %s :Kill message set.", OperServ, from);
01143 }
01144 } else if (!strcasecmp(args[3], "warn")
01145 || !strcasecmp(args[3], "warnmsg")) {
01146 char tmpbuf[8192] = "";
01147 if (args[4][0] == '\0' || !strcasecmp(args[4], "none")) {
01148 if (rule->warn_msg)
01149 FREE(rule->warn_msg);
01150 rule->warn_msg = NULL;
01151 sSend(":%s NOTICE %s :Warning message cleared.", OperServ,
01152 from);
01153 } else {
01154 parse_str(args, numargs, 4, tmpbuf, IRCBUF);
01155 if (strlen(tmpbuf) > MEMOLEN) {
01156 sSend
01157 (":%s NOTICE %s :Warning message cannot exceed %d characters.",
01158 OperServ, from, MEMOLEN);
01159 return RET_EFAULT;
01160 }
01161 if (rule->warn_msg)
01162 FREE(rule->warn_msg);
01163 rule->warn_msg = strdup(tmpbuf);
01164 if (!rule->warn_msg) {
01165 logDump(corelog,
01166 "Error allocating (%d) bytes of memory for clonerule warn message. (%s!%s@%s)",
01167 strlen(tmpbuf), from, nick->user, nick->host);
01168 sSend
01169 (":%s GLOBOPS :Error allocating (%d) bytes of memory for clonerule arn message. (%s!%s@%s)",
01170 NickServ, strlen(tmpbuf), from, nick->user,
01171 nick->host);
01172 return RET_MEMORY;
01173 }
01174 sSend(":%s NOTICE %s :Warning message set.", OperServ,
01175 from);
01176 }
01177 } else {
01178 sSend
01179 (":%s NOTICE %s :Valid settings are: FLAGS, HTRIGGER, UTRIGGER, KILLMSG, and WARNMSG",
01180 OperServ, from);
01181 sSend(":%s NOTICE %s :Valid flags are: %s", OperServ, from,
01182 flagstring(~0, cloneset_bits));
01183 return RET_OK;
01184 }
01185 saveTriggerData();
01186 return RET_OK_DB;
01187 case CLONEARG_DEL:
01188 if (!(rule = GetCrule(args[2]))) {
01189 sSend(":%s NOTICE %s :\2%s\2: No such trigger default.",
01190 OperServ, from, args[2]);
01191 return RET_NOTARGET;
01192 }
01193 RemoveCrule(rule);
01194 sSend(":%s NOTICE %s :Trigger rule for %s removed.", OperServ,
01195 from, rule->mask);
01196 sSend(":%s GLOBOPS :%s removing trigger rule for \2%s\2", OperServ,
01197 from, rule->mask);
01198 if (rule->kill_msg)
01199 FREE(rule->kill_msg);
01200 if (rule->warn_msg)
01201 FREE(rule->warn_msg);
01202 FREE(rule);
01203 saveTriggerData();
01204 return RET_OK_DB;
01205 }
01206 sSend(":%s NOTICE %s :Huh?", OperServ, from);
01207 return RET_SYNTAX;
01208 }
01209
01210
01211
01216 OCMD(os_trigger)
01217 {
01218 char *from = nick->nick;
01219 char user[USERLEN];
01220 char host[HOSTLEN];
01221 HostClone *hc;
01222 UserClone *uc;
01223 int i;
01224
01225 if (numargs < 2) {
01226 sSend(":%s NOTICE %s :Default host trigger: \2%i\2", OperServ, from,
01227 DEFHOSTCLONETRIGGER);
01228 sSend(":%s NOTICE %s :Default user trigger: \2%i\2", OperServ, from,
01229 DEFUSERCLONETRIGGER);
01230 sSend(":%s NOTICE %s :/OPERSERV trigger list' to show "
01231 "any outstanding alerts.", OperServ, from);
01232
01233 return RET_OK;
01234 }
01235
01236 if (numargs >= 2 && !str_cmp(args[1], "list")) {
01237 listCloneAlerts(nick);
01238
01239 return RET_OK;
01240 }
01241
01242
01243
01244
01245
01246 if (index(args[1], '@')) {
01247 user[0] = host[0] = '\0';
01248 sscanf(args[1], "%[^@]@%s", user, host);
01249
01250 hc = getCloneData(host);
01251 if (hc != NULL)
01252 uc = getUserCloneData(hc, user);
01253 else
01254 uc = NULL;
01255
01256 if ((uc == NULL) || (hc == NULL)) {
01257 sSend(":%s NOTICE %s :No such user@host (%s@%s), ", OperServ,
01258 from, user, host);
01259
01260 return RET_NOTARGET;
01261 }
01262
01263 if (numargs < 3) {
01264 sSend(":%s NOTICE %s :%s@%s has %d/%d clones (total/trigger)",
01265 OperServ, from, user, host, uc->clones, uc->trigger);
01266
01267 return RET_OK;
01268 }
01269
01270 i = atoi(args[2]);
01271 if (i <= 0) {
01272 sSend(":%s NOTICE %s :Please specify a proper trigger level",
01273 OperServ, from);
01274
01275 return RET_EFAULT;
01276 }
01277
01278 uc->trigger = i;
01279 sSend(":%s GLOBOPS :%s@%s retriggered to %d by %s", OperServ, user,
01280 host, i, from);
01281
01282 return RET_OK_DB;
01283 }
01284
01285
01286
01287
01288 strncpyzt(host, args[1], HOSTLEN);
01289
01290 hc = getCloneData(host);
01291 if (hc == NULL) {
01292 sSend(":%s NOTICE %s :%s does not exist", OperServ, from, host);
01293
01294 return RET_NOTARGET;
01295 }
01296
01297 if (numargs < 3) {
01298 sSend(":%s NOTICE %s :%s has %i/%i clones (total/trigger)",
01299 OperServ, from, host, hc->clones, hc->trigger);
01300
01301 return RET_OK;
01302 }
01303
01304 i = atoi(args[2]);
01305
01306 if (i <= 0) {
01307 sSend(":%s NOTICE %s :Please specify a proper trigger level",
01308 OperServ, from);
01309
01310 return RET_EFAULT;
01311 }
01312
01313 hc->trigger = i;
01314 sSend(":%s GLOBOPS :%s retriggered to %i by %s", OperServ, host, i,
01315 from);
01316 return RET_OK_DB;
01317 }
01318
01319
01320
01325
01326 OCMD(os_match)
01327 {
01328 char *from = nick->nick;
01329
01330 if (numargs > 2)
01331 sSend(":%s NOTICE %s :match(%s, %s) returns %i", OperServ, from,
01332 args[1], args[2], match(args[1], args[2]));
01333 return RET_OK;
01334 }
01335
01336
01337
01346 OCMD(os_cloneset)
01347 {
01348 char *from = nick->nick;
01349 HostClone *hc;
01350
01351 if (numargs < 2) {
01352 sSend(":%s NOTICE %s :You must specify at least an address",
01353 OperServ, from);
01354 return RET_SYNTAX;
01355 }
01356
01357 hc = getCloneData(args[1]);
01358 if (hc == NULL) {
01359 sSend(":%s NOTICE %s :No such host %s", OperServ, from, args[1]);
01360
01361 return RET_NOTARGET;
01362 }
01363
01364 if (numargs < 3) {
01365 sSend(":%s NOTICE %s :%s has flags:%s%s.", OperServ, from, args[1],
01366 ((hc->flags & CLONE_KILLFLAG) ? " Auto Remove" : ""),
01367 ((hc->flags & CLONE_IGNOREFLAG) ? "Ignore all" : ""));
01368 } else {
01369 if (!strcasecmp(args[2], "kill"))
01370 hc->flags |= CLONE_KILLFLAG;
01371 else if (!strcasecmp(args[2], "-kill"))
01372 hc->flags &= ~CLONE_KILLFLAG;
01373 else if (!strcasecmp(args[2], "ok"))
01374 hc->flags |= CLONE_OK;
01375 else if (!strcasecmp(args[2], "-ok"))
01376 hc->flags &= ~CLONE_OK;
01377 else if (!strcasecmp(args[2], "ignore"))
01378 hc->flags |= CLONE_IGNOREFLAG;
01379 else if (!strcasecmp(args[2], "-ignore"))
01380 hc->flags &= ~CLONE_IGNOREFLAG;
01381 else {
01382 sSend(":%s NOTICE %s :Unknown flag %s", OperServ, from,
01383 args[2]);
01384 return RET_EFAULT;
01385 }
01386
01387 sSend(":%s GLOBOPS :%s changed cloneflags for %s (now %s%s)",
01388 OperServ, from, hc->host,
01389 ((hc->flags & CLONE_KILLFLAG) ? " Auto Remove" : ""),
01390 ((hc->flags & CLONE_IGNOREFLAG) ? "Ignore all" : ""));
01391 return RET_OK_DB;
01392 }
01393 return RET_OK;
01394 }
01395
01396
01397
01398
01399
01400 OCMD(os_remsra)
01401 {
01402 char NickGetEnc(RegNickList *);
01403 char *from = nick->nick;
01404 RegNickList *root;
01405
01406 if (!nick->reg)
01407 return RET_NOPERM;
01408
01409 if ((numargs < 3)
01410 || (!(nick->reg->opflags & OREMROOT))
01411 || !Valid_pw(args[2], nick->reg->password, NickGetEnc(nick->reg))) {
01412 operlog->log(nick, OS_REMSRA, (numargs > 1 ? args[1] : ""), 0,
01413 "failed");
01414 sSend(":%s NOTICE %s :Unknown command %s.\r\n"
01415 ":%s NOTICE %s :Please try /msg %s HELP", OperServ, from,
01416 args[0], OperServ, from, OperServ);
01417 return RET_NOPERM;
01418 }
01419
01420 root = getRegNickData(args[1]);
01421 if (!root)
01422 return RET_NOPERM;
01423 delOpData(root);
01424 root->opflags &= ~(OROOT | OPROT);
01425 if (root->opflags)
01426 addOpData(root);
01427 sSend(":%s NOTICE %s :Rootflags for %s removed", OperServ, from,
01428 args[1]);
01429 operlog->log(nick, OS_REMSRA, (numargs > 1 ? args[1] : ""));
01430 return RET_OK_DB;
01431 }
01432
01437
01438
01439
01440
01441 OCMD(os_grpop)
01442 {
01443 char *from = nick->nick;
01444 RegNickList *grpop;
01445 int bucket;
01446
01447 if (!nick->reg)
01448 return RET_NOPERM;
01449
01450 if ((numargs < 2) || (!strcasecmp(args[1], "list"))) {
01451 sSend(":%s NOTICE %s :Now listing GRP-Ops:", OperServ, from);
01452
01453 for (bucket = 0; bucket < NICKHASHSIZE; bucket++) {
01454 for (grpop = LIST_FIRST(&RegNickHash[bucket]); grpop;
01455 grpop = LIST_NEXT(grpop, rn_lst))
01456 if (grpop->opflags & OGRP)
01457 sSend(":%s NOTICE %s :%s", OperServ, from,
01458 grpop->nick);
01459 }
01460 return RET_OK;
01461 }
01462
01463 if (!isRoot(nick)) {
01464 sSend(":%s NOTICE %s :Permission denied.", OperServ, from);
01465 return RET_NOPERM;
01466 }
01467
01468 if ((!strcasecmp(args[1], "convert"))) {
01469 sSend(":%s NOTICE %s :Now converting GRP-Ops to new format.",
01470 OperServ, from);
01471
01472 for (bucket = 0; bucket < NICKHASHSIZE; bucket++) {
01473 for (grpop = LIST_FIRST(&RegNickHash[bucket]); grpop;
01474 grpop = LIST_NEXT(grpop, rn_lst))
01475 if (grpop->flags & NGRPOP) {
01476 grpop->flags &= ~NGRPOP;
01477 grpop->opflags |= OGRP;
01478 sSend(":%s NOTICE %s :%s", OperServ, from,
01479 grpop->nick);
01480 }
01481 }
01482 return RET_OK_DB;
01483 }
01484
01485 sSend(":%s NOTICE %s :-- This command is deprecated, use setop.",
01486 OperServ, from);
01487
01488 if (!strcasecmp(args[1], "del")) {
01489 if (numargs != 3) {
01490 sSend
01491 (":%s NOTICE %s :Improper format. Try /msg %s help grpop",
01492 OperServ, from, OperServ);
01493 return RET_SYNTAX;
01494 }
01495 if ((grpop = getRegNickData(args[2])) != NULL) {
01496 grpop->opflags &= ~OGRP;
01497 if (!grpop->opflags)
01498 delOpData(grpop);
01499 sSend(":%s NOTICE %s :%s no longer flagged GRP-op.", OperServ,
01500 from, args[2]);
01501 } else {
01502 sSend
01503 (":%s NOTICE %s :Target nickname, %s, is not registered. No changes made.",
01504 OperServ, from, args[2]);
01505 return RET_NOTARGET;
01506 }
01507 } else if (!strcasecmp(args[1], "add")) {
01508 if (numargs != 3) {
01509 sSend
01510 (":%s NOTICE %s :Improper format. Try /msg %s help grpop",
01511 OperServ, from, OperServ);
01512 return RET_SYNTAX;
01513 }
01514 if ((grpop = getRegNickData(args[2])) != 0) {
01515 if (!grpop->opflags)
01516 addOpData(grpop);
01517 grpop->opflags |= OGRP;
01518 sSend(":%s NOTICE %s :%s flagged GRP-op.", OperServ, from,
01519 args[2]);
01520 } else {
01521 sSend
01522 (":%s NOTICE %s :Target nickname, %s, is not registered. No changes made.",
01523 OperServ, from, args[2]);
01524 return RET_NOTARGET;
01525 }
01526 }
01527 return RET_OK_DB;
01528 }
01529
01530
01531
01538 OCMD(os_override)
01539 {
01540 UserList *tmp = nick;
01541 char *orig_cmd, *service;
01542 char stuff[IRCBUF + 25];
01543 int i = 0;
01544
01545 if (!nick)
01546 return RET_NOPERM;
01547
01548 if (!isOper(nick) || os_user_override) {
01549 sSend(":%s NOTICE %s :I don't think so!", ChanServ, nick->nick);
01550 return RET_INVALID;
01551 }
01552
01553 if ((!nick->reg || !(nick->reg->opflags & OACC)) && !isRoot(nick)) {
01554 sSend(":%s NOTICE %s "
01555 ":You do not have the proper flags to use this command.",
01556 OperServ, nick->nick);
01557 return RET_NOPERM;
01558 }
01559
01560 if (numargs < 3) {
01561 sSend
01562 (":%s NOTICE %s :Override user access restrictions, but for what service and what command?",
01563 ChanServ, nick->nick);
01564 return RET_SYNTAX;
01565 }
01566
01567 orig_cmd = args[0];
01568 service = args[1];
01569 for (i = 0; i < (numargs - 2); i++)
01570 args[i] = args[i + 2];
01571 args[numargs - 1] = NULL;
01572 numargs -= 2;
01573 os_user_override = nick;
01574
01575 parse_str(args, numargs, 0, stuff, IRCBUF);
01576 operlog->log(nick, OS_OVERRIDE, args[1], LOGF_OK, "%s", stuff);
01577
01578 if (!strncasecmp(service, OperServ, strlen(OperServ)))
01579 sendToOperServ(tmp, args, numargs);
01580 else if (!strncasecmp(service, NickServ, strlen(NickServ)))
01581 sendToNickServ(tmp, args, numargs);
01582 else if (!strncasecmp(service, ChanServ, strlen(ChanServ)))
01583 sendToChanServ(tmp, args, numargs);
01584 else if (!strncasecmp(service, MemoServ, strlen(MemoServ)))
01585 sendToMemoServ(tmp, args, numargs);
01586 else if (!strncasecmp(service, InfoServ, strlen(InfoServ)))
01587 sendToInfoServ(tmp, args, numargs);
01588 else if (!strncasecmp(service, GameServ, strlen(GameServ)))
01589 sendToGameServ(tmp, args, numargs);
01590 else
01591 sSend(":%s NOTICE %s :No such service.", OperServ, nick->nick);
01592 os_user_override = NULL;
01593 return RET_KILLED;
01594 }
01595
01596
01597
01599 OCMD(os_strike)
01600 {
01601 #ifdef USE_SQL
01602 char *tnick, *p, *mask;
01603 char query_ln[(2 * (NICKLEN + 1)) + 512];
01604
01605 if (!isRoot(nick)) {
01606 sSend
01607 (":%s NOTICE %s :This is a test command and requires root acess currently.",
01608 OperServ, nick->nick);
01609 return RET_NOPERM;
01610 }
01611
01612 if (numargs < 2 || !strchr(args[1], '!') || !strchr(args[1], '@')
01613 || !strchr(args[1], '.')) {
01614 sSend(":%s NOTICE %s :Usage: /operserv strike nick!user@host",
01615 OperServ, nick->nick);
01616 return RET_SYNTAX;
01617 }
01618
01619 tnick = args[1];
01620 p = strchr(args[1], '!');
01621 *p = '\0';
01622 mask = p + 1;
01623
01624 sprintf(query_ln,
01625 "INSERT into strikes (setby, nick, mask, status, auth_num) "
01626 "VALUES (\'%s\', \'%s\', \'%s\', 0, %ld);", nick->nick, tnick,
01627 mask, (time(NULL) / 100000) ^ nick->nick[0]);
01628 if (PQsendQuery(dbConn, query_ln) < 0) {
01629 sSend
01630 (":%s NOTICE %s :Services is busy at the moment, please try again in a bit.",
01631 OperServ, nick->nick);
01632 return RET_OK_DB;
01633 }
01634 #else
01635 sSend(":%s NOTICE %s :This test command is not compiled in.", OperServ,
01636 nick->nick);
01637 #endif
01638 return RET_OK;
01639 }
01640
01641
01642
01649 OCMD(os_heal)
01650 {
01651 const char *from = nick->nick;
01652 UserList *tarNick;
01653
01654 if (numargs < 2) {
01655 sSend(":%s NOTICE %s :Syntax Error.", OperServ, from);
01656 sSend(":%s NOTICE %s :Usage: /msg %s HEAL <nick>", OperServ, from,
01657 OperServ);
01658 return RET_FAIL;
01659 }
01660
01661 if (!(tarNick = getNickData(args[1]))) {
01662 sSend(":%s NOTICE %s :No user by that name.", OperServ, from);
01663 return RET_NOTARGET;
01664 }
01665
01666 sSend(":%s HEAL %s", NickServ, args[1]);
01667 tarNick->oflags &= ~(NISAHURT);
01668 return RET_OK;
01669 }
01670
01671
01672
01673
01674
01675 OCMD(os_nixghost) {
01676 if (numargs < 2)
01677 return RET_SYNTAX;
01678 if (isGhost(args[1])) {
01679 sSend(":%s QUIT :nixxed", args[1]);
01680 }
01681 }
01682
01683
01684
01685