boolean make_fifo(char *fifo_path) { boolean fifo_exists; if ((fifo_exists = isfifo(fifo_path)) == FALSE) { if (mkfifo(fifo_path, 0664) < 0) log_printf("Make fifo %s failed: %m\n", fifo_path); else fifo_exists = TRUE; } if (fifo_exists) check_modes(fifo_path, 0664); return fifo_exists; }
static boolean make_dir(char *dir) { boolean dir_exists; if ((dir_exists = isdir(dir)) == FALSE) { exec_wait("sudo mkdir -p $F", dir); if ((dir_exists = isdir(dir)) == FALSE) log_printf("Make directory failed: %s\n", dir); else dir_exists = TRUE; } if (dir_exists) check_modes(dir, 0775); return dir_exists; }
/** * The /cs clear command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_clear(User * u) { char *chan = strtok(NULL, " "); char *what = strtok(NULL, " "); char tmp[BUFSIZE]; Channel *c; ChannelInfo *ci; if (!what) { syntax_error(s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX); } else if (!(c = findchan(chan))) { notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan); } else if (!(ci = c->ci)) { notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan); } else if (ci->flags & CI_VERBOTEN) { notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan); } else if (!u || !check_access(u, ci, CA_CLEAR)) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); } else if (stricmp(what, "bans") == 0) { char *av[2]; int i; /* Save original ban info */ int count = c->bancount; char **bans = scalloc(sizeof(char *) * count, 1); for (i = 0; i < count; i++) bans[i] = sstrdup(c->bans[i]); for (i = 0; i < count; i++) { av[0] = sstrdup("-b"); av[1] = bans[i]; anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_BANS, chan); free(bans); } else if (ircd->except && stricmp(what, "excepts") == 0) { char *av[2]; int i; /* Save original except info */ int count = c->exceptcount; char **excepts = scalloc(sizeof(char *) * count, 1); for (i = 0; i < count; i++) excepts[i] = sstrdup(c->excepts[i]); for (i = 0; i < count; i++) { av[0] = sstrdup("-e"); av[1] = excepts[i]; anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_EXCEPTS, chan); free(excepts); } else if (ircd->invitemode && stricmp(what, "invites") == 0) { char *av[2]; int i; /* Save original except info */ int count = c->invitecount; char **invites = scalloc(sizeof(char *) * count, 1); for (i = 0; i < count; i++) invites[i] = sstrdup(c->invite[i]); for (i = 0; i < count; i++) { av[0] = sstrdup("-I"); av[1] = invites[i]; anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_INVITES, chan); free(invites); } else if (stricmp(what, "modes") == 0) { char buf[BUFSIZE], *end = buf; char *argv[2]; if (c->mode) { /* Clear modes the bulk of the modes */ anope_cmd_mode(whosends(ci), c->name, "%s", ircd->modestoremove); argv[0] = sstrdup(ircd->modestoremove); chan_set_modes(whosends(ci), c, 1, argv, 0); free(argv[0]); /* to prevent the internals from complaining send -k, -L, -f by themselves if we need to send them - TSL */ if (c->key) { anope_cmd_mode(whosends(ci), c->name, "-k %s", c->key); argv[0] = sstrdup("-k"); argv[1] = c->key; chan_set_modes(whosends(ci), c, 2, argv, 0); free(argv[0]); } if (ircd->Lmode && c->redirect) { anope_cmd_mode(whosends(ci), c->name, "-L %s", c->redirect); argv[0] = sstrdup("-L"); argv[1] = c->redirect; chan_set_modes(whosends(ci), c, 2, argv, 0); free(argv[0]); } if (ircd->fmode && c->flood) { if (flood_mode_char_remove) { anope_cmd_mode(whosends(ci), c->name, "%s %s", flood_mode_char_remove, c->flood); argv[0] = sstrdup(flood_mode_char_remove); argv[1] = c->flood; chan_set_modes(whosends(ci), c, 2, argv, 0); free(argv[0]); } else { if (debug) { alog("debug: flood_mode_char_remove was not set unable to remove flood/throttle modes"); } } } check_modes(c); } /* TODO: decide if the above implementation is better than this one. */ if (0) { CBModeInfo *cbmi = cbmodeinfos; CBMode *cbm; do { if (c->mode & cbmi->flag) *end++ = cbmi->mode; } while ((++cbmi)->flag != 0); cbmi = cbmodeinfos; do { if (cbmi->getvalue && (c->mode & cbmi->flag) && !(cbmi->flags & CBM_MINUS_NO_ARG)) { char *value = cbmi->getvalue(c); if (value) { *end++ = ' '; while (*value) *end++ = *value++; /* Free the value */ cbm = &cbmodes[(int) cbmi->mode]; cbm->setvalue(c, NULL); } } } while ((++cbmi)->flag != 0); *end = 0; anope_cmd_mode(whosends(ci), c->name, "-%s", buf); c->mode = 0; check_modes(c); } notice_lang(s_ChanServ, u, CHAN_CLEARED_MODES, chan); } else if (stricmp(what, "ops") == 0) { char *av[3]; struct c_userlist *cu, *next; if (ircd->svsmode_ucmode) { av[0] = sstrdup(chan); anope_cmd_svsmode_chan(av[0], "-o", NULL); if (ircd->owner) { anope_cmd_svsmode_chan(av[0], ircd->ownerunset, NULL); } if (ircd->protect || ircd->admin) { anope_cmd_svsmode_chan(av[0], ircd->adminunset, NULL); } for (cu = c->users; cu; cu = next) { next = cu->next; av[0] = sstrdup(chan); if (!chan_has_user_status(c, cu->user, CUS_OP)) { if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) { if (!chan_has_user_status(c, cu->user, CUS_OWNER)) { continue; } else { snprintf(tmp, BUFSIZE, "%so", ircd->ownerunset); av[1] = sstrdup(tmp); } } else { snprintf(tmp, BUFSIZE, "%so", ircd->adminunset); av[1] = sstrdup(tmp); } } else { av[1] = sstrdup("-o"); } av[2] = sstrdup(cu->user->nick); do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; av[0] = sstrdup(chan); if (!chan_has_user_status(c, cu->user, CUS_OP)) { if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) { if (!chan_has_user_status(c, cu->user, CUS_OWNER)) { continue; } else { snprintf(tmp, BUFSIZE, "%so", ircd->ownerunset); av[1] = sstrdup(tmp); } } else { snprintf(tmp, BUFSIZE, "%so", ircd->adminunset); av[1] = sstrdup(tmp); } } else { av[1] = sstrdup("-o"); } av[2] = sstrdup(cu->user->nick); anope_cmd_mode(whosends(ci), av[0], "%s :%s", av[1], av[2]); do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } } notice_lang(s_ChanServ, u, CHAN_CLEARED_OPS, chan); } else if (ircd->halfop && stricmp(what, "hops") == 0) { char *av[3]; struct c_userlist *cu, *next; for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_HALFOP)) continue; av[0] = sstrdup(chan); av[1] = sstrdup("-h"); av[2] = sstrdup(cu->user->nick); if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(av[0], av[1], NULL); do_cmode(s_ChanServ, 3, av); break; } else { anope_cmd_mode(whosends(ci), av[0], "%s :%s", av[1], av[2]); } do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_HOPS, chan); } else if (stricmp(what, "voices") == 0) { char *av[3]; struct c_userlist *cu, *next; for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_VOICE)) continue; av[0] = sstrdup(chan); av[1] = sstrdup("-v"); av[2] = sstrdup(cu->user->nick); if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(av[0], av[1], NULL); do_cmode(s_ChanServ, 3, av); break; } else { anope_cmd_mode(whosends(ci), av[0], "%s :%s", av[1], av[2]); } do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_VOICES, chan); } else if (stricmp(what, "users") == 0) { char *av[3]; struct c_userlist *cu = NULL, *next = NULL; char buf[256]; snprintf(buf, sizeof(buf), "CLEAR USERS command from %s", u->nick); for (cu = c->users; cu; cu = next) { next = cu->next; if ((cu->user->mode & UMODE_q)) { continue; } av[0] = sstrdup(chan); av[1] = sstrdup(cu->user->nick); av[2] = sstrdup(buf); anope_cmd_kick(whosends(ci), av[0], av[1], av[2]); do_kick(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_USERS, chan); } else { syntax_error(s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX); } return MOD_CONT; }
int main(int argc, char *argv[]) { int fifo; int i, n; char *opt, *arg, *equal_arg, *homedir, *user; char *line, *eol, buf[4096]; pgm_name = argv[0]; bcm_host_init(); time(&pikrellcam.t_now); config_set_defaults(); for (i = 1; i < argc; i++) get_arg_pass1(argv[i]); if (!config_load(pikrellcam.config_file)) config_save(pikrellcam.config_file); if (!motion_regions_config_load(pikrellcam.motion_regions_config_file)) motion_regions_config_save(pikrellcam.motion_regions_config_file); if (!at_commands_config_load(pikrellcam.at_commands_config_file)) at_commands_config_save(pikrellcam.at_commands_config_file); for (i = 1; i < argc; i++) { if (get_arg_pass1(argv[i])) continue; opt = argv[i]; /* Just for initial install-pikrellcam.sh run to create config files. */ if (!strcmp(opt, "-quit")) exit(0); /* Accept: --opt arg -opt arg opt=arg --opt=arg -opt=arg */ for (i = 0; i < 2; ++i) if (*opt == '-') ++opt; if ((equal_arg = strchr(opt, '=')) != NULL) { *equal_arg++ = '\0'; arg = equal_arg; ++i; } else arg = argv[i + 1]; /* For camera parameters, do not set the camera, only replace | values in the parameter table. */ if ( !config_set_option(opt, arg, TRUE) && !mmalcam_config_parameter_set(opt, arg, FALSE) ) { log_printf("Bad arg: %s\n", opt); exit(1); } } homedir = getpwuid(geteuid())->pw_dir; user = strrchr(homedir, '/'); pikrellcam.effective_user = strdup(user ? user + 1 : "pi"); if (*pikrellcam.log_file != '/') { snprintf(buf, sizeof(buf), "%s/%s", pikrellcam.install_dir, pikrellcam.log_file); dup_string(&pikrellcam.log_file, buf); } if (*pikrellcam.media_dir != '/') { snprintf(buf, sizeof(buf), "%s/%s", pikrellcam.install_dir, pikrellcam.media_dir); dup_string(&pikrellcam.media_dir, buf); } strftime(buf, sizeof(buf), "%F %T", localtime(&pikrellcam.t_now)); log_printf("\n%s ==== PiKrellCam started ====\n", buf); snprintf(buf, sizeof(buf), "%s/%s", pikrellcam.install_dir, "www"); check_modes(buf, 0775); asprintf(&pikrellcam.command_fifo, "%s/www/FIFO", pikrellcam.install_dir); asprintf(&pikrellcam.script_dir, "%s/scripts", pikrellcam.install_dir); asprintf(&pikrellcam.mjpeg_filename, "%s/mjpeg.jpg", pikrellcam.mjpeg_dir); log_printf("using FIFO: %s\n", pikrellcam.command_fifo); log_printf("using mjpeg: %s\n", pikrellcam.mjpeg_filename); /* Subdirs must match www/config.php and the init script is supposed | to take care of that. */ asprintf(&pikrellcam.video_dir, "%s/%s", pikrellcam.media_dir, PIKRELLCAM_VIDEO_SUBDIR); asprintf(&pikrellcam.still_dir, "%s/%s", pikrellcam.media_dir, PIKRELLCAM_STILL_SUBDIR); asprintf(&pikrellcam.timelapse_dir, "%s/%s", pikrellcam.media_dir, PIKRELLCAM_TIMELAPSE_SUBDIR); if (!make_dir(pikrellcam.media_dir)) exit(1); snprintf(buf, sizeof(buf), "%s/scripts-dist/init $I $m $M $P $G", pikrellcam.install_dir); exec_wait(buf, NULL); /* User may have enabled a mount disk on media_dir */ exec_wait(pikrellcam.on_startup_cmd, NULL); check_modes(pikrellcam.media_dir, 0775); if ( !make_dir(pikrellcam.mjpeg_dir) || !make_dir(pikrellcam.video_dir) || !make_dir(pikrellcam.still_dir) || !make_dir(pikrellcam.timelapse_dir) || !make_fifo(pikrellcam.command_fifo) ) exit(1); if ((fifo = open(pikrellcam.command_fifo, O_RDONLY | O_NONBLOCK)) < 0) { log_printf("Failed to open FIFO: %s. %m\n", pikrellcam.command_fifo); exit(1); } fcntl(fifo, F_SETFL, 0); read(fifo, buf, sizeof(buf)); sun_times_init(); camera_start(); config_timelapse_load_status(); signal(SIGINT, signal_quit); signal(SIGTERM, signal_quit); signal(SIGCHLD, event_child_signal); while (1) { usleep(1000000 / EVENT_LOOP_FREQUENCY); event_process(); /* Process lines in the FIFO. Single lines via an echo "xxx" > FIFO | or from a web page may not have a terminating \n. | Local scripts may dump multiple \n terminated lines into the FIFO. */ if ((n = read(fifo, buf, sizeof(buf) - 2)) > 0) { if (buf[n - 1] != '\n') buf[n++] = '\n'; /* ensures all lines in buf end in \n */ buf[n] = '\0'; line = buf; eol = strchr(line, '\n'); while (eol > line) { *eol++ = '\0'; command_process(line); while (*eol == '\n') ++eol; line = eol; eol = strchr(line, '\n'); } } } return 0; }
int do_clear(User *u, Channel *c, int type) { /* 1= Modes * 2= Bans * 3= Excepts * 4= Invites * 5= Ops * 6= Hops * 7= Voices * 8= Users */ char tmp[BUFSIZE]; /* Clear Channel Modes */ if (type == 1) { char *argv[2]; notice(c->ci->bi->nick, c->name, "CLEAR MODES command from %s", u->nick); if (c->mode) { /* Clear modes the bulk of the modes */ xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s", ircd->modestoremove); argv[0] = sstrdup(ircd->modestoremove); chan_set_modes(c->ci->bi->nick, c, 1, argv, 0); free(argv[0]); if (c->key) { xanadu_cmd_mode(c->ci->bi->nick, c->name, "-k %s", c->key); argv[0] = sstrdup("-k"); argv[1] = c->key; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } if (ircd->Lmode && c->redirect) { xanadu_cmd_mode(c->ci->bi->nick, c->name, "-L %s", c->redirect); argv[0] = sstrdup("-L"); argv[1] = c->redirect; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } if (ircd->fmode && c->flood) { if (flood_mode_char_remove) { xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s %s", flood_mode_char_remove, c->flood); argv[0] = sstrdup(flood_mode_char_remove); argv[1] = c->flood; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } } check_modes(c); } /* Clear Channel Bans */ } else if (type == 2) { char *av[2]; int i, count = c->bancount; char **bans = scalloc(sizeof(char *) * count, 1); /*count = c->bancount;*/ notice(c->ci->bi->nick, c->name, "CLEAR BANS command from %s", u->nick); /* Save original ban info */ for (i = 0; i < count; i++) bans[i] = sstrdup(c->bans[i]); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(c->name, "-b", NULL); for (i = 0; i < count; i++) { av[0] = sstrdup("-b"); av[1] = bans[i]; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[0]); free(av[1]); } } else { for (i = 0; i < count; i++) { av[0] = sstrdup("-b"); av[1] = bans[i]; xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[0]); free(av[1]); } } free(bans); /* Clear Channel Excepts */ } else if (ircd->except && type == 3) { char *av[2]; int i, count = c->exceptcount; char **excepts = scalloc(sizeof(char *) * count, 1); notice(c->ci->bi->nick, c->name, "CLEAR EXCEPTS command from %s", u->nick); /* Save original except info */ for (i = 0; i < count; i++) excepts[i] = sstrdup(c->excepts[i]); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(c->name, "-e", NULL); for (i = 0; i < count; i++) { av[0] = sstrdup("-e"); av[1] = excepts[i]; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[1]); free(av[0]); } } else { for (i = 0; i < count; i++) { av[0] = sstrdup("-e"); av[1] = excepts[i]; xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[1]); free(av[0]); } } free(excepts); } else if (!(ircd->except) && type == 3) { moduleNoticeLang(c->ci->bi->nick, u, LANG_EXCEPTS_UNSUPPORTED); /* Clear Channel Invites */ } else if (ircd->invitemode && type == 4) { char *av[2]; int i, count = c->invitecount; char **invites = scalloc(sizeof(char *) * count, 1); notice(c->ci->bi->nick, c->name, "CLEAR INVITES command from %s", u->nick); /* Save original invite info */ for (i = 0; i < count; i++) invites[i] = sstrdup(c->invite[i]); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(c->name, "-I", NULL); for (i = 0; i < count; i++) { av[0] = sstrdup("-I"); av[1] = invites[i]; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[1]); free(av[0]); } } else { for (i = 0; i < count; i++) { av[0] = sstrdup("-I"); av[1] = invites[i]; xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[1]); free(av[0]); } } free(invites); } else if (!(ircd->invitemode) && type == 4) { moduleNoticeLang(c->ci->bi->nick, u, LANG_INVITEMODE_UNSUPPORTED); /* Clear Channel OPs */ } else if (type == 5) { char *av[4]; struct c_userlist *cu, *next; char buf[BUFSIZE]; int ac; notice(c->ci->bi->nick, c->name, "CLEAR OPS command from %s", u->nick); av[0] = c->name; if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(c->name, "-o", NULL); if (ircd->owner) { xanadu_cmd_svsmode_chan(c->name, ircd->ownerunset, NULL); } if (ircd->protect || ircd->admin) { xanadu_cmd_svsmode_chan(c->name, ircd->adminunset, NULL); } for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_OP)) { if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) { if (!chan_has_user_status(c, cu->user, CUS_OWNER)) { continue; } else { snprintf(tmp, BUFSIZE, "%so", ircd->ownerunset); } } else { snprintf(tmp, BUFSIZE, "%so", ircd->adminunset); } } else { snprintf(tmp, BUFSIZE, "-o"); } if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[2] = tmp; av[3] = cu->user->nick; ac = 4; } else { av[1] = tmp; av[2] = cu->user->nick; ac = 3; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_OP)) { if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) { if (!chan_has_user_status(c, cu->user, CUS_OWNER)) { continue; } else { snprintf(tmp, BUFSIZE, "%so", ircd->ownerunset); } } else { snprintf(tmp, BUFSIZE, "%so", ircd->adminunset); } } else { snprintf(tmp, BUFSIZE, "-o"); } if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[2] = tmp; av[3] = cu->user->nick; ac = 4; } else { av[1] = tmp; av[2] = cu->user->nick; ac = 3; } xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s :%s", tmp, cu->user->nick); do_cmode(c->ci->bi->nick, ac, av); } } /* Clear Channel HOPs */ } else if (ircd->halfop && type == 6) { char *av[4]; struct c_userlist *cu, *next; char buf[BUFSIZE]; int ac; notice(c->ci->bi->nick, c->name, "CLEAR HOPS command from %s", u->nick); av[0] = c->name; if (ircdcap->tsmode) av[2] = sstrdup("-h"); else av[1] = sstrdup("-h"); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(c->name, "-h", NULL); for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_HALFOP)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_HALFOP)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } xanadu_cmd_mode(c->ci->bi->nick, c->name, "-h :%s", cu->user->nick); do_cmode(c->ci->bi->nick, ac, av); } } if (ircdcap->tsmode) free(av[2]); else free(av[1]); } else if (!(ircd->halfop) && type == 6) { moduleNoticeLang(c->ci->bi->nick, u, LANG_HOPS_UNSUPPORTED); /* Clear Channel Voices */ } else if (type == 7) { char *av[4]; struct c_userlist *cu, *next; char buf[BUFSIZE]; int ac; notice(c->ci->bi->nick, c->name, "CLEAR VOICES command from %s", u->nick); av[0] = c->name; if (ircdcap->tsmode) av[2] = sstrdup("-v"); else av[1] = sstrdup("-v"); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(av[0], "-v", NULL); for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_VOICE)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_VOICE)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } xanadu_cmd_mode(c->ci->bi->nick, c->name, "-v :%s", cu->user->nick); do_cmode(c->ci->bi->nick, ac, av); } } if (ircdcap->tsmode) free(av[2]); else free(av[1]); /* Clear Channel Users */ } else if (type == 8) { char *av[3]; struct c_userlist *cu, *next; char buf[256]; snprintf(buf, sizeof(buf), "CLEAR USERS command from %s", u->nick); notice(c->ci->bi->nick, c->name, buf); av[0] = c->name; av[2] = buf; for (cu = c->users; cu; cu = next) { next = cu->next; av[1] = cu->user->nick; xanadu_cmd_kick(c->ci->bi->nick, av[0], av[1], av[2]); do_kick(c->ci->bi->nick, 3, av); } } /* Should NEVER happen, therefor if it does, stop processing */ else { alog("[bs_fantasy_ext] An error has occured while processing CLEAR !!!"); return MOD_STOP; } return MOD_CONT; }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) { const Anope::string &chan = params[0]; const Anope::string &chdesc = params.size() > 1 ? params[1] : ""; User *u = source.u; Channel *c = findchan(params[0]); ChannelInfo *ci = cs_findchan(params[0]); if (readonly) source.Reply(_("Sorry, channel registration is temporarily disabled.")); else if (u->Account()->HasFlag(NI_UNCONFIRMED)) source.Reply(_("You must confirm your account before you can register a channel.")); else if (chan[0] == '&') source.Reply(_("Local channels cannot be registered.")); else if (chan[0] != '#') source.Reply(CHAN_SYMBOL_REQUIRED); else if (!ircdproto->IsChannelValid(chan)) source.Reply(CHAN_X_INVALID, chan.c_str()); else if (ci) source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str()); else if (c && !c->HasUserStatus(u, CMODE_OP)) source.Reply(_("You must be a channel operator to register the channel.")); else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit")) source.Reply(u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg); else { ci = new ChannelInfo(chan); ci->SetFounder(u->Account()); if (!chdesc.empty()) ci->desc = chdesc; ci->mode_locks = def_mode_locks; for (ChannelInfo::ModeList::iterator it = ci->mode_locks.begin(), it_end = ci->mode_locks.end(); it != it_end; ++it) { it->second.setter = u->nick; it->second.ci = ci; } if (c && !c->topic.empty()) { ci->last_topic = c->topic; ci->last_topic_setter = c->topic_setter; ci->last_topic_time = c->topic_time; } else ci->last_topic_setter = source.owner->nick; Log(LOG_COMMAND, u, this, ci); source.Reply(_("Channel \002%s\002 registered under your nickname: %s"), chan.c_str(), u->nick.c_str()); /* Implement new mode lock */ if (c) { check_modes(c); ChannelMode *cm; if (u->FindChannel(c) != NULL) { /* On most ircds you do not receive the admin/owner mode till its registered */ if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER))) c->SetMode(NULL, cm, u->nick); else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT))) c->RemoveMode(NULL, cm, u->nick); } /* Mark the channel as persistent */ if (c->HasMode(CMODE_PERM)) ci->SetFlag(CI_PERSIST); /* Persist may be in def cflags, set it here */ else if (ci->HasFlag(CI_PERSIST) && (cm = ModeManager::FindChannelModeByName(CMODE_PERM))) c->SetMode(NULL, CMODE_PERM); } FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(ci)); } return; }
/* yeah, this should be fun. */ void channel_mode(channel_t *chan, uint8_t parc, char *parv[]) { boolean_t matched = FALSE; int i, parpos = 0, whatt = MTYPE_NUL; char *pos = parv[0]; mychan_t *mc; chanuser_t *cu = NULL; if ((!pos) || (*pos == '\0')) return; if (!chan) return; /* SJOIN modes of 0 means no change */ if (*pos == '0') return; /* assumed that the parc is correct. ircd does, too. */ for (; *pos != '\0'; pos++) { matched = FALSE; if (*pos == '+') { whatt = MTYPE_ADD; continue; } if (*pos == '-') { whatt = MTYPE_DEL; continue; } for (i = 0; mode_list[i].mode != '\0'; i++) { if (*pos == mode_list[i].mode) { matched = TRUE; if (whatt == MTYPE_ADD) chan->modes |= mode_list[i].value; else chan->modes &= ~mode_list[i].value; break; } } if (matched == TRUE) continue; for (i = 0; ignore_mode_list[i].mode != '\0'; i++) { if (*pos == ignore_mode_list[i].mode) { matched = TRUE; parpos++; break; } } if (matched == TRUE) continue; for (i = 0; ignore_mode_list[i].mode != '\0'; i++) { if (*pos == ignore_mode_list[i].mode) { matched = TRUE; parpos++; break; } } if (matched == TRUE) continue; if (*pos == 'l') { if (whatt == MTYPE_ADD) { chan->modes |= CMODE_LIMIT; chan->limit = atoi(parv[++parpos]); } else { chan->modes &= ~CMODE_LIMIT; chan->limit = 0; } continue; } if (*pos == 'k') { if (whatt == MTYPE_ADD) { chan->modes |= CMODE_KEY; chan->key = sstrdup(parv[++parpos]); } else { chan->modes &= ~CMODE_KEY; free(chan->key); chan->key = NULL; /* ratbox typically sends either the key or a `*' on -k, so you * should eat a parameter */ parpos++; } continue; } for (i = 0; status_mode_list[i].mode != '\0'; i++) { if (*pos == status_mode_list[i].mode) { cu = chanuser_find(chan, user_find(parv[++parpos])); if (cu == NULL) { slog(LG_ERROR, "channel_mode(): MODE %s %c%c %s", chan->name, (whatt == MTYPE_ADD) ? '+' : '-', status_mode_list[i].value, parv[parpos]); matched = TRUE; } if (matched == TRUE) break; matched = TRUE; if (whatt == MTYPE_ADD) { cu->modes |= status_mode_list[i].value; /* see if they did something we have to undo */ if ((mc = mychan_find(cu->chan->name))) { myuser_t *mu = cu->user->myuser; if ((MC_SECURE & mc->flags) && (status_mode_list[i].mode == 'o')) { char hostbuf[BUFSIZE]; snprintf(hostbuf, BUFSIZE, "%s!%s@%s", cu->user->nick, cu->user->user, cu->user->host); if ((!is_founder(mc, mu)) && (cu->user != svs.svs) && (!is_xop(mc, mu, (CA_AOP | CA_SOP))) && (!chanacs_find_host(mc, hostbuf, CA_AOP))) { /* they were opped and aren't on the list, deop them */ cmode(svs.nick, mc->name, "-o", cu->user->nick); cu->modes &= ~status_mode_list[i].value; } } } } else { if (cu->user == svs.svs) { slog(LG_DEBUG, "channel_mode(): deopped on %s, rejoining", cu->chan->name); /* we were deopped, part and join */ part(cu->chan->name, svs.nick); join(cu->chan->name, svs.nick); continue; } cu->modes &= ~status_mode_list[i].value; } break; } } if (matched == TRUE) continue; slog(LG_DEBUG, "channel_mode(): mode %c not matched", *pos); } check_modes(mychan_find(chan->name)); }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) { const Anope::string &channel = params[0]; const Anope::string &target = params[1]; Anope::string what = params.size() > 2 ? params[2] : ""; User *u = source.u; ChannelInfo *ci = cs_findchan(params[0]); if (ci == NULL) { source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); return; } if (!ci->AccessFor(u).HasPriv("SET")) { source.Reply(ACCESS_DENIED); return; } ChannelInfo *target_ci = cs_findchan(target); if (!target_ci) { source.Reply(CHAN_X_NOT_REGISTERED, target.c_str()); return; } if (!IsFounder(u, ci) || !IsFounder(u, target_ci)) { source.Reply(ACCESS_DENIED); return; } if (what.equals_ci("ALL")) what.clear(); if (what.empty()) { delete target_ci; target_ci = new ChannelInfo(*ci); target_ci->name = target; RegisteredChannelList[target_ci->name] = target_ci; target_ci->c = findchan(target_ci->name); if (target_ci->c) { target_ci->c->ci = target_ci; check_modes(target_ci->c); ChannelMode *cm; if (u->FindChannel(target_ci->c) != NULL) { /* On most ircds you do not receive the admin/owner mode till its registered */ if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER))) target_ci->c->SetMode(NULL, cm, u->nick); else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT))) target_ci->c->RemoveMode(NULL, cm, u->nick); } /* Mark the channel as persistent */ if (target_ci->c->HasMode(CMODE_PERM)) target_ci->SetFlag(CI_PERSIST); /* Persist may be in def cflags, set it here */ else if (target_ci->HasFlag(CI_PERSIST) && (cm = ModeManager::FindChannelModeByName(CMODE_PERM))) target_ci->c->SetMode(NULL, CMODE_PERM); if (target_ci->bi && target_ci->c->FindUser(target_ci->bi) == NULL) target_ci->bi->Join(target_ci->c, &Config->BotModeList); } if (target_ci->c && !target_ci->c->topic.empty()) { target_ci->last_topic = target_ci->c->topic; target_ci->last_topic_setter = target_ci->c->topic_setter; target_ci->last_topic_time = target_ci->c->topic_time; } else target_ci->last_topic_setter = source.owner->nick; FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(target_ci)); source.Reply(_("All settings from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str()); } else if (what.equals_ci("ACCESS")) { for (unsigned i = 0; i < ci->GetAccessCount(); ++i) { ChanAccess *taccess = ci->GetAccess(i); AccessProvider *provider = taccess->provider; ChanAccess *newaccess = provider->Create(); newaccess->ci = target_ci; newaccess->mask = taccess->mask; newaccess->creator = taccess->creator; newaccess->last_seen = taccess->last_seen; newaccess->created = taccess->created; newaccess->Unserialize(taccess->Serialize()); target_ci->AddAccess(newaccess); } source.Reply(_("All access entries from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str()); } else if (what.equals_ci("AKICK")) { target_ci->ClearAkick(); for (unsigned i = 0; i < ci->GetAkickCount(); ++i) { AutoKick *akick = ci->GetAkick(i); if (akick->HasFlag(AK_ISNICK)) target_ci->AddAkick(akick->creator, akick->nc, akick->reason, akick->addtime, akick->last_used); else target_ci->AddAkick(akick->creator, akick->mask, akick->reason, akick->addtime, akick->last_used); } source.Reply(_("All akick entries from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str()); } else if (what.equals_ci("BADWORDS")) { target_ci->ClearBadWords(); for (unsigned i = 0; i < ci->GetBadWordCount(); ++i) { BadWord *bw = ci->GetBadWord(i); target_ci->AddBadWord(bw->word, bw->type); } source.Reply(_("All badword entries from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str()); } else { this->OnSyntaxError(source, ""); return; } Log(LOG_COMMAND, u, this, ci) << "to clone " << (what.empty() ? "everything from it" : what) << " to " << target_ci->name; return; }
/** * The /cs register command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_register(User * u) { char *chan = strtok(NULL, " "); char *pass = strtok(NULL, " "); char *desc = strtok(NULL, ""); NickCore *nc; Channel *c; ChannelInfo *ci; struct u_chaninfolist *uc; int is_servadmin = is_services_admin(u); char founderpass[PASSMAX + 1]; char tmp_pass[PASSMAX]; if (readonly) { notice_lang(s_ChanServ, u, CHAN_REGISTER_DISABLED); return MOD_CONT; } if (checkDefCon(DEFCON_NO_NEW_CHANNELS)) { notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED); return MOD_CONT; } if (!desc) { syntax_error(s_ChanServ, u, "REGISTER", CHAN_REGISTER_SYNTAX); } else if (*chan == '&') { notice_lang(s_ChanServ, u, CHAN_REGISTER_NOT_LOCAL); } else if (*chan != '#') { notice_lang(s_ChanServ, u, CHAN_SYMBOL_REQUIRED); } else if (!xanadu_valid_chan(chan)) { notice_lang(s_ChanServ, u, CHAN_X_INVALID, chan); } else if (!u->na || !(nc = u->na->nc)) { notice_lang(s_ChanServ, u, CHAN_MUST_REGISTER_NICK, s_NickServ); } else if (!nick_recognized(u)) { notice_lang(s_ChanServ, u, CHAN_MUST_IDENTIFY_NICK, s_NickServ, s_NickServ); } else if (!(c = findchan(chan))) { notice_lang(s_ChanServ, u, CHAN_REGISTER_NONE_CHANNEL, chan); } else if ((ci = cs_findchan(chan)) != NULL) { if (ci->flags & CI_VERBOTEN) { alog("%s: Attempt to register FORBIDden channel %s by %s!%s@%s", s_ChanServ, ci->name, u->nick, u->username, u->host); notice_lang(s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan); } else { notice_lang(s_ChanServ, u, CHAN_ALREADY_REGISTERED, chan); } } else if (!stricmp(chan, "#")) { notice_lang(s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan); } else if (!chan_has_user_status(c, u, CUS_OP)) { notice_lang(s_ChanServ, u, CHAN_MUST_BE_CHANOP); } else if (!is_servadmin && nc->channelmax > 0 && nc->channelcount >= nc->channelmax) { notice_lang(s_ChanServ, u, nc->channelcount > nc-> channelmax ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, nc->channelmax); } else if (stricmp(u->nick, pass) == 0 || (StrictPasswords && strlen(pass) < 5)) { notice_lang(s_ChanServ, u, MORE_OBSCURE_PASSWORD); } else if (!(ci = makechan(chan))) { alog("%s: makechan() failed for REGISTER %s", s_ChanServ, chan); notice_lang(s_ChanServ, u, CHAN_REGISTRATION_FAILED); } else if (strscpy(founderpass, pass, PASSMAX + 1), enc_encrypt_in_place(founderpass, PASSMAX) < 0) { alog("%s: Couldn't encrypt password for %s (REGISTER)", s_ChanServ, chan); notice_lang(s_ChanServ, u, CHAN_REGISTRATION_FAILED); delchan(ci); } else { c->ci = ci; ci->c = c; ci->bantype = CSDefBantype; ci->flags = CSDefFlags; ci->mlock_on = ircd->defmlock; ci->memos.memomax = MSMaxMemos; ci->last_used = ci->time_registered; ci->founder = nc; if (strlen(pass) > PASSMAX) notice_lang(s_ChanServ, u, PASSWORD_TRUNCATED, PASSMAX); memset(pass, 0, strlen(pass)); memcpy(ci->founderpass, founderpass, PASSMAX); ci->desc = sstrdup(desc); if (c->topic) { ci->last_topic = sstrdup(c->topic); strscpy(ci->last_topic_setter, c->topic_setter, NICKMAX); ci->last_topic_time = c->topic_time; } else { /* Set this to something, otherwise it will maliform the topic */ strscpy(ci->last_topic_setter, s_ChanServ, NICKMAX); } ci->bi = NULL; ci->botflags = BSDefFlags; ci->founder->channelcount++; alog("%s: Channel '%s' registered by %s!%s@%s", s_ChanServ, chan, u->nick, u->username, u->host); notice_lang(s_ChanServ, u, CHAN_REGISTERED, chan, u->nick); if(enc_decrypt(ci->founderpass,tmp_pass,PASSMAX) == 1) { notice_lang(s_ChanServ, u, CHAN_PASSWORD_IS, ci->founderpass); } uc = scalloc(sizeof(*uc), 1); uc->next = u->founder_chans; uc->prev = NULL; if (u->founder_chans) u->founder_chans->prev = uc; u->founder_chans = uc; uc->chan = ci; /* Implement new mode lock */ check_modes(c); /* On most ircds you do not receive the admin/owner mode till its registered */ if (ircd->admin) { xanadu_cmd_mode(s_ChanServ, chan, "%s %s", ircd->adminset, u->nick); } if (ircd->owner && ircd->ownerset) { xanadu_cmd_mode(s_ChanServ, chan, "%s %s", ircd->ownerset, u->nick); } send_event(EVENT_CHAN_REGISTERED, 1, chan); } return MOD_CONT; }
static void cs_cmd_set_mlock(struct sourceinfo *si, int parc, char *parv[]) { struct mychan *mc; char modebuf[32], *end, c; int dir = MTYPE_NUL; int newlock_on = 0, newlock_off = 0, newlock_limit = 0, flag = 0; unsigned int mask, changed; bool mask_ext; char newlock_key[KEYLEN + 1]; char newlock_ext[ignore_mode_list_size][512]; bool newlock_ext_off[ignore_mode_list_size]; char newext[512]; char ext_plus[ignore_mode_list_size + 1]; char ext_minus[ignore_mode_list_size + 1]; size_t i; char *letters = strtok(parv[1], " "); char *arg; struct metadata *md; if (!(mc = mychan_find(parv[0]))) { command_fail(si, fault_nosuch_target, STR_IS_NOT_REGISTERED, parv[0]); return; } if (!chanacs_source_has_flag(mc, si, CA_SET)) { if (ircd->oper_only_modes == 0 || !has_priv(si, PRIV_CHAN_CMODES) || !has_priv(si, PRIV_CHAN_ADMIN)) { command_fail(si, fault_noprivs, STR_NOT_AUTHORIZED); return; } mask = ~ircd->oper_only_modes; mask_ext = true; } else { mask = has_priv(si, PRIV_CHAN_CMODES) ? 0 : ircd->oper_only_modes; mask_ext = false; } for (i = 0; i < ignore_mode_list_size; i++) { newlock_ext[i][0] = '\0'; newlock_ext_off[i] = false; } newlock_key[0] = '\0'; while (letters && *letters) { if (*letters != '+' && *letters != '-' && dir == MTYPE_NUL) { letters++; continue; } switch ((c = *letters++)) { case '+': dir = MTYPE_ADD; break; case '-': dir = MTYPE_DEL; break; case 'k': if (dir == MTYPE_ADD) { arg = strtok(NULL, " "); if (!arg) { command_fail(si, fault_badparams, _("You need to specify a value for mode +%c."), 'k'); return; } else if (strlen(arg) > KEYLEN) { command_fail(si, fault_badparams, _("MLOCK key is too long (%zu > %u)."), strlen(arg), KEYLEN); return; } else if (strchr(arg, ',') || arg[0] == ':') { command_fail(si, fault_badparams, _("MLOCK key contains invalid characters.")); return; } mowgli_strlcpy(newlock_key, arg, sizeof newlock_key); newlock_off &= ~CMODE_KEY; } else { newlock_key[0] = '\0'; newlock_off |= CMODE_KEY; } break; case 'l': if (dir == MTYPE_ADD) { arg = strtok(NULL, " "); if(!arg) { command_fail(si, fault_badparams, _("You need to specify a value for mode +%c."), 'l'); return; } if (atol(arg) <= 0) { command_fail(si, fault_badparams, _("You must specify a positive integer for limit.")); return; } newlock_limit = atol(arg); newlock_off &= ~CMODE_LIMIT; } else { newlock_limit = 0; newlock_off |= CMODE_LIMIT; } break; default: flag = mode_to_flag(c); if (flag) { if (dir == MTYPE_ADD) { newlock_on |= flag; newlock_off &= ~flag; } else { newlock_off |= flag; newlock_on &= ~flag; } break; } for (i = 0; ignore_mode_list[i].mode != '\0'; i++) { if (c == ignore_mode_list[i].mode) { if (dir == MTYPE_ADD) { arg = strtok(NULL, " "); if(!arg) { command_fail(si, fault_badparams, _("You need to specify a value for mode +%c."), c); return; } if (strlen(arg) > 350) { command_fail(si, fault_badparams, _("Invalid value \2%s\2 for mode +%c."), arg, c); return; } if ((mc->chan == NULL || mc->chan->extmodes[i] == NULL || strcmp(mc->chan->extmodes[i], arg)) && !ignore_mode_list[i].check(arg, mc->chan, mc, si->su, si->smu)) { command_fail(si, fault_badparams, _("Invalid value \2%s\2 for mode +%c."), arg, c); return; } mowgli_strlcpy(newlock_ext[i], arg, sizeof newlock_ext[i]); newlock_ext_off[i] = false; } else { newlock_ext[i][0] = '\0'; newlock_ext_off[i] = true; } } } } } // note: the following does not treat +lk and extmodes correctly changed = ((newlock_on ^ mc->mlock_on) | (newlock_off ^ mc->mlock_off)); changed &= ~mask; /* if they're only allowed to alter oper only modes, require * them to actually change such modes -- jilles */ if (!changed && mask_ext) { command_fail(si, fault_noprivs, _("You may only alter \2+%s\2 modes."), flags_to_string(~mask)); return; } // save it to mychan, leave the modes in mask unchanged -- jilles mc->mlock_on = (newlock_on & ~mask) | (mc->mlock_on & mask); mc->mlock_off = (newlock_off & ~mask) | (mc->mlock_off & mask); if (!(mask & CMODE_LIMIT)) mc->mlock_limit = newlock_limit; if (!(mask & CMODE_KEY)) { sfree(mc->mlock_key); mc->mlock_key = *newlock_key != '\0' ? sstrdup(newlock_key) : NULL; } ext_plus[0] = '\0'; ext_minus[0] = '\0'; if (mask_ext) { md = metadata_find(mc, "private:mlockext"); if (md != NULL) { arg = md->value; while (*arg != '\0') { modebuf[0] = *arg; modebuf[1] = '\0'; mowgli_strlcat(arg[1] == ' ' || arg[1] == '\0' ? ext_minus : ext_plus, modebuf, ignore_mode_list_size + 1); arg++; while (*arg != ' ' && *arg != '\0') arg++; while (*arg == ' ') arg++; } } } else { newext[0] = '\0'; for (i = 0; i < ignore_mode_list_size; i++) { if (newlock_ext[i][0] != '\0' || newlock_ext_off[i]) { if (*newext != '\0') { modebuf[0] = ' '; modebuf[1] = '\0'; mowgli_strlcat(newext, modebuf, sizeof newext); } modebuf[0] = ignore_mode_list[i].mode; modebuf[1] = '\0'; mowgli_strlcat(newext, modebuf, sizeof newext); mowgli_strlcat(newlock_ext_off[i] ? ext_minus : ext_plus, modebuf, ignore_mode_list_size + 1); if (!newlock_ext_off[i]) mowgli_strlcat(newext, newlock_ext[i], sizeof newext); } } if (newext[0] != '\0') metadata_add(mc, "private:mlockext", newext); else metadata_delete(mc, "private:mlockext"); } end = modebuf; *end = 0; if (mc->mlock_on || mc->mlock_key || mc->mlock_limit || *ext_plus) end += snprintf(end, sizeof(modebuf) - (end - modebuf), "+%s%s%s%s", flags_to_string(mc->mlock_on), mc->mlock_key ? "k" : "", mc->mlock_limit ? "l" : "", ext_plus); if (mc->mlock_off || *ext_minus) end += snprintf(end, sizeof(modebuf) - (end - modebuf), "-%s%s%s%s", flags_to_string(mc->mlock_off), mc->mlock_off & CMODE_KEY ? "k" : "", mc->mlock_off & CMODE_LIMIT ? "l" : "", ext_minus); if (*modebuf) { command_success_nodata(si, _("The MLOCK for \2%s\2 has been set to \2%s\2."), mc->name, modebuf); logcommand(si, CMDLOG_SET, "SET:MLOCK: \2%s\2 to \2%s\2", mc->name, modebuf); verbose(mc, "\2%s\2 set the mode lock to \2%s\2", get_source_name(si), modebuf); } else { command_success_nodata(si, _("The MLOCK for \2%s\2 has been removed."), mc->name); logcommand(si, CMDLOG_SET, "SET:MLOCK:NONE: \2%s\2", mc->name); } if (changed & ircd->oper_only_modes) logcommand(si, CMDLOG_SET, "SET:MLOCK: \2%s\2 to \2%s\2 by \2%s\2", mc->name, *modebuf != '\0' ? modebuf : "+", get_oper_name(si)); check_modes(mc, true); if (mc->chan != NULL) mlock_sts(mc->chan); return; }
int do_clear(User *u, Channel *c, int type) { /* 1= Modes * 2= Bans * 3= Excepts * 4= Invites * 5= Ops * 6= Hops * 7= Voices * 8= Users */ /* Clear Channel Modes */ if (type == 1) { char *argv[2]; notice(c->ci->bi->nick, c->name, "CLEAR MODES command from %s", u->nick); if (c->mode) { /* Clear modes the bulk of the modes */ anope_cmd_mode(c->ci->bi->nick, c->name, "%s", ircd->modestoremove); argv[0] = sstrdup(ircd->modestoremove); chan_set_modes(c->ci->bi->nick, c, 1, argv, 0); free(argv[0]); if (c->key) { anope_cmd_mode(c->ci->bi->nick, c->name, "-k %s", c->key); argv[0] = sstrdup("-k"); argv[1] = c->key; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } if (ircd->Lmode && c->redirect) { anope_cmd_mode(c->ci->bi->nick, c->name, "-L %s", c->redirect); argv[0] = sstrdup("-L"); argv[1] = c->redirect; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } if (ircd->fmode && c->flood) { if (flood_mode_char_remove) { anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", flood_mode_char_remove, c->flood); argv[0] = sstrdup(flood_mode_char_remove); argv[1] = c->flood; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } } check_modes(c); } /* Clear Channel Bans */ } else if (type == 2) { char *av[2]; Entry *ban, *next; notice(c->ci->bi->nick, c->name, "CLEAR BANS command from %s", u->nick); if (c->bans && c->bans->count) { if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(c->name, "-b", NULL); av[0] = "-b"; for (ban = c->bans->entries; ban; ban = next) { next = ban->next; av[1] = ban->mask; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } else { av[0] = "-b"; for (ban = c->bans->entries; ban; ban = next) { next = ban->next; av[1] = ban->mask; anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } } /* Clear Channel Excepts */ } else if (ircd->except && type == 3) { char *av[2]; Entry *except, *next; notice(c->ci->bi->nick, c->name, "CLEAR EXCEPTS command from %s", u->nick); if (c->excepts && c->excepts->count) { if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(c->name, "-e", NULL); av[0] = "-e"; for (except = c->excepts->entries; except; except = next) { next = except->next; av[1] = except->mask; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } else { av[0] = "-e"; for (except = c->excepts->entries; except; except = next) { next = except->next; av[1] = except->mask; anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } } } else if (!(ircd->except) && type == 3) { noticeLang(c->ci->bi->nick, u, LANG_EXCEPTS_UNSUPPORTED); /* Clear Channel Invites */ } else if (ircd->invitemode && type == 4) { char *av[2]; Entry *invite, *next; notice(c->ci->bi->nick, c->name, "CLEAR INVITES command from %s", u->nick); if (c->invites && c->invites->count) { if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(c->name, "-e", NULL); av[0] = "-I"; for (invite = c->invites->entries; invite; invite = next) { next = invite->next; av[1] = invite->mask; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } else { av[0] = "-I"; for (invite = c->invites->entries; invite; invite = next) { next = invite->next; av[1] = invite->mask; anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } } } else if (!(ircd->invitemode) && type == 4) { noticeLang(c->ci->bi->nick, u, LANG_INVITEMODE_UNSUPPORTED); /* Clear Channel OPs */ } else if (type == 5) { char *av[6]; /* The max we have to hold: chan, ts, modes(max3), nick, nick, nick */ int ac, isop, isadmin, isown, count, i; char buf[BUFSIZE], tmp[BUFSIZE], tmp2[BUFSIZE]; struct c_userlist *cu, *next; notice(c->ci->bi->nick, c->name, "CLEAR OPS command from %s", u->nick); av[0] = c->name; if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(c->name, "-o", NULL); if (ircd->owner) { anope_cmd_svsmode_chan(c->name, ircd->ownerunset, NULL); } if (ircd->protect || ircd->admin) { anope_cmd_svsmode_chan(c->name, ircd->adminunset, NULL); } for (cu = c->users; cu; cu = next) { next = cu->next; isop = chan_has_user_status(c, cu->user, CUS_OP); isadmin = chan_has_user_status(c, cu->user, CUS_PROTECT); isown = chan_has_user_status(c, cu->user, CUS_OWNER); count = (isop ? 1 : 0) + (isadmin ? 1 : 0) + (isown ? 1 : 0); if (!isop && !isadmin && !isown) continue; snprintf(tmp, BUFSIZE, "-%s%s%s", (isop ? "o" : ""), (isadmin ? ircd->adminunset+1 : ""), (isown ? ircd->ownerunset+1 : "")); if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[2] = tmp; /* We have to give as much nicks as modes.. - Viper */ for (i = 0; i < count; i++) av[i+3] = cu->user->nick; ac = 3 + i; } else { av[1] = tmp; /* We have to give as much nicks as modes.. - Viper */ for (i = 0; i < count; i++) av[i+2] = cu->user->nick; ac = 2 + i; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; isop = chan_has_user_status(c, cu->user, CUS_OP); isadmin = chan_has_user_status(c, cu->user, CUS_PROTECT); isown = chan_has_user_status(c, cu->user, CUS_OWNER); count = (isop ? 1 : 0) + (isadmin ? 1 : 0) + (isown ? 1 : 0); if (!isop && !isadmin && !isown) continue; snprintf(tmp, BUFSIZE, "-%s%s%s", (isop ? "o" : ""), (isadmin ? ircd->adminunset+1 : ""), (isown ? ircd->ownerunset+1 : "")); /* We need to send the IRCd a nick for every mode.. - Viper */ snprintf(tmp2, BUFSIZE, "%s %s %s", (isop ? cu->user->nick : ""), (isadmin ? cu->user->nick : ""), (isown ? cu->user->nick : "")); if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[2] = tmp; /* We have to give as much nicks as modes.. - Viper */ for (i = 0; i < count; i++) av[i+3] = cu->user->nick; ac = 3 + i; anope_cmd_mode(c->ci->bi->nick, av[0], "%s %s", av[2], tmp2); } else { av[1] = tmp; /* We have to give as much nicks as modes.. - Viper */ for (i = 0; i < count; i++) av[i+2] = cu->user->nick; ac = 2 + i; anope_cmd_mode(c->ci->bi->nick, av[0], "%s %s", av[1], tmp2); } do_cmode(c->ci->bi->nick, ac, av); } } /* Clear Channel HOPs */ } else if (ircd->halfop && type == 6) { char *av[4]; struct c_userlist *cu, *next; char buf[BUFSIZE]; int ac; notice(c->ci->bi->nick, c->name, "CLEAR HOPS command from %s", u->nick); av[0] = c->name; if (ircdcap->tsmode) av[2] = sstrdup("-h"); else av[1] = sstrdup("-h"); if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(c->name, "-h", NULL); for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_HALFOP)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_HALFOP)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } anope_cmd_mode(c->ci->bi->nick, c->name, "-h %s", cu->user->nick); do_cmode(c->ci->bi->nick, ac, av); } } if (ircdcap->tsmode) free(av[2]); else free(av[1]); } else if (!(ircd->halfop) && type == 6) { noticeLang(c->ci->bi->nick, u, LANG_HOPS_UNSUPPORTED); /* Clear Channel Voices */ } else if (type == 7) { char *av[4]; struct c_userlist *cu, *next; char buf[BUFSIZE]; int ac; notice(c->ci->bi->nick, c->name, "CLEAR VOICES command from %s", u->nick); av[0] = c->name; if (ircdcap->tsmode) av[2] = sstrdup("-v"); else av[1] = sstrdup("-v"); if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(av[0], "-v", NULL); for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_VOICE)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_VOICE)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } anope_cmd_mode(c->ci->bi->nick, c->name, "-v %s", cu->user->nick); do_cmode(c->ci->bi->nick, ac, av); } } if (ircdcap->tsmode) free(av[2]); else free(av[1]); /* Clear Channel Users */ } else if (type == 8) { char *av[3]; struct c_userlist *cu, *next; char buf[256]; snprintf(buf, sizeof(buf), "CLEAR USERS command from %s", u->nick); notice(c->ci->bi->nick, c->name, buf); av[0] = c->name; av[2] = buf; for (cu = c->users; cu; cu = next) { next = cu->next; av[1] = cu->user->nick; anope_cmd_kick(c->ci->bi->nick, av[0], av[1], av[2]); do_kick(c->ci->bi->nick, 3, av); } } /* Should NEVER happen, therefor if it does, stop processing */ else { alog("[bs_fantasy_ext] An error has occured while processing CLEAR !!!"); return MOD_STOP; } return MOD_CONT; }