Beispiel #1
0
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;
	}
Beispiel #2
0
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;
	}
Beispiel #3
0
/**
 * 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;
}
Beispiel #4
0
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;
	}
Beispiel #5
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;
}
Beispiel #6
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params)
	{
		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;
	}
Beispiel #7
0
/* 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));
}
Beispiel #8
0
	void Execute(CommandSource &source, const std::vector<Anope::string> &params)
	{
		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;
}
Beispiel #10
0
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;
}
Beispiel #11
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 */

	/* 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;
}