Ejemplo n.º 1
0
static int send_waveform_to_fd(char *waveform, int length, int fd) {

    int res;
    int x;
#ifdef __PPC__
    char c;
#endif

    res = fork();
    if (res < 0)
        ast_log(LOG_WARNING, "Fork failed\n");
    if (res)
        return res;
    for (x=0; x<256; x++) {
        if (x != fd)
            close(x);
    }
    if (ast_opt_high_priority)
        ast_set_priority(0);

    /*IAS */
#ifdef __PPC__
    for( x=0; x<length; x+=2)
    {
        c = *(waveform+x+1);
        *(waveform+x+1)=*(waveform+x);
        *(waveform+x)=c;
    }
#endif

    write(fd,waveform,length);
    close(fd);
    exit(0);
}
Ejemplo n.º 2
0
static int send_waveform_to_fd(char *waveform, int length, int fd)
{
    int res;
#if __BYTE_ORDER == __BIG_ENDIAN
    int x;
    char c;
#endif

    res = ast_safe_fork(0);
    if (res < 0)
        ast_log(LOG_WARNING, "Fork failed\n");
    if (res) {
        return res;
    }
    dup2(fd, 0);
    ast_close_fds_above_n(0);
    if (ast_opt_high_priority)
        ast_set_priority(0);
#if __BYTE_ORDER == __BIG_ENDIAN
    for (x = 0; x < length; x += 2) {
        c = *(waveform + x + 1);
        *(waveform + x + 1) = *(waveform + x);
        *(waveform + x) = c;
    }
#endif

    if (write(0, waveform, length) < 0) {
        /* Cannot log -- all FDs are already closed */
    }

    close(fd);
    _exit(0);
}
Ejemplo n.º 3
0
static int mp3play(const char *filename, unsigned int sampling_rate, int fd)
{
	int res;
	char sampling_rate_str[8];

	res = ast_safe_fork(0);
	if (res < 0) 
		ast_log(LOG_WARNING, "Fork failed\n");
	if (res) {
		return res;
	}
	if (ast_opt_high_priority)
		ast_set_priority(0);

	dup2(fd, STDOUT_FILENO);
	ast_close_fds_above_n(STDERR_FILENO);

	snprintf(sampling_rate_str, 8, "%u", sampling_rate);

	/* Execute mpg123, but buffer if it's a net connection */
	if (!strncasecmp(filename, "http://", 7) && strstr(filename, ".m3u")) {
	    char buffer_size_str[8];
	    snprintf(buffer_size_str, 8, "%u", (int) 0.5*2*sampling_rate/1000); // 0.5 seconds for a live stream
		/* Most commonly installed in /usr/local/bin */
	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
		/* But many places has it in /usr/bin */
	    execl(MPG_123, "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
		/* As a last-ditch effort, try to use PATH */
	    execlp("mpg123", "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
	}
	else if (!strncasecmp(filename, "http://", 7)) {
	    char buffer_size_str[8];
	    snprintf(buffer_size_str, 8, "%u", 6*2*sampling_rate/1000); // 6 seconds for a remote MP3 file
		/* Most commonly installed in /usr/local/bin */
	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
		/* But many places has it in /usr/bin */
	    execl(MPG_123, "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
		/* As a last-ditch effort, try to use PATH */
	    execlp("mpg123", "mpg123", "-q", "-s", "-b", buffer_size_str, "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
	}
	else if (strstr(filename, ".m3u")) {
		/* Most commonly installed in /usr/local/bin */
	    execl(LOCAL_MPG_123, "mpg123", "-q", "-z", "-s", "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
		/* But many places has it in /usr/bin */
	    execl(MPG_123, "mpg123", "-q", "-z", "-s", "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
		/* As a last-ditch effort, try to use PATH */
	    execlp("mpg123", "mpg123", "-q", "-z", "-s",  "-f", "8192", "--mono", "-r", sampling_rate_str, "-@", filename, (char *)NULL);
	}
	else {
		/* Most commonly installed in /usr/local/bin */
	    execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
		/* But many places has it in /usr/bin */
	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
		/* As a last-ditch effort, try to use PATH */
	    execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", sampling_rate_str, filename, (char *)NULL);
	}
	/* Can't use ast_log since FD's are closed */
	fprintf(stderr, "Execute of mpg123 failed\n");
	_exit(0);
}
Ejemplo n.º 4
0
static int icesencode(char *filename, int fd)
{
	int res;

	res = ast_safe_fork(0);
	if (res < 0) 
		ast_log(LOG_WARNING, "Fork failed\n");
	if (res) {
		return res;
	}

	if (ast_opt_high_priority)
		ast_set_priority(0);
	dup2(fd, STDIN_FILENO);
	ast_close_fds_above_n(STDERR_FILENO);

	/* Most commonly installed in /usr/local/bin 
	 * But many places has it in /usr/bin 
	 * As a last-ditch effort, try to use PATH
	 */
	execl(path_LOCAL "ices2", "ices", filename, SENTINEL);
	execl(path_BIN "ices2", "ices", filename, SENTINEL);
	execlp("ices2", "ices", filename, SENTINEL);

	ast_debug(1, "Couldn't find ices version 2, attempting to use ices version 1.");

	execl(path_LOCAL "ices", "ices", filename, SENTINEL);
	execl(path_BIN "ices", "ices", filename, SENTINEL);
	execlp("ices", "ices", filename, SENTINEL);

	ast_log(LOG_WARNING, "Execute of ices failed, could not find command.\n");
	close(fd);
	_exit(0);
}
Ejemplo n.º 5
0
static pid_t spawn_ras(struct ast_channel *chan, char *args)
{
    pid_t pid;
    char *c;

    char *argv[PPP_MAX_ARGS];
    int argc = 0;
    char *stringp=NULL;

    /* Start by forking */
    pid = ast_safe_fork(1);
    if (pid) {
        return pid;
    }

    /* Execute RAS on File handles */
    dup2(ast_channel_fd(chan, 0), STDIN_FILENO);

    /* Drop high priority */
    if (ast_opt_high_priority)
        ast_set_priority(0);

    /* Close other file descriptors */
    ast_close_fds_above_n(STDERR_FILENO);

    /* Reset all arguments */
    memset(argv, 0, sizeof(argv));

    /* First argument is executable, followed by standard
       arguments for DAHDI PPP */
    argv[argc++] = PPP_EXEC;
    argv[argc++] = "nodetach";

    /* And all the other arguments */
    stringp=args;
    c = strsep(&stringp, ",");
    while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
        argv[argc++] = c;
        c = strsep(&stringp, ",");
    }

    argv[argc++] = "plugin";
    argv[argc++] = "dahdi.so";
    argv[argc++] = "stdin";

    /* Finally launch PPP */
    execv(PPP_EXEC, argv);
    fprintf(stderr, "Failed to exec PPPD!\n");
    exit(1);
}
Ejemplo n.º 6
0
static int mp3play(char *filename, int fd)
{
	int res;
	int x;
	sigset_t fullset, oldset;

	sigfillset(&fullset);
	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);

	res = fork();
	if (res < 0) 
		ast_log(LOG_WARNING, "Fork failed\n");
	if (res) {
		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
		return res;
	}
	if (ast_opt_high_priority)
		ast_set_priority(0);
	signal(SIGPIPE, SIG_DFL);
	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);

	dup2(fd, STDOUT_FILENO);
	for (x=STDERR_FILENO + 1;x<256;x++) {
		if (x != STDOUT_FILENO)
			close(x);
	}
	/* Execute mpg123, but buffer if it's a net connection */
	if (!strncasecmp(filename, "http://", 7)) {
		/* Most commonly installed in /usr/local/bin */
	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* But many places has it in /usr/bin */
	    execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* As a last-ditch effort, try to use PATH */
	    execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024",  "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
	}
	else {
		/* Most commonly installed in /usr/local/bin */
	    execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* But many places has it in /usr/bin */
	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* As a last-ditch effort, try to use PATH */
	    execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
	}
	ast_log(LOG_WARNING, "Execute of mpg123 failed\n");
	_exit(0);
}
Ejemplo n.º 7
0
static int mp3play(const char *filename, int fd)
{
	int res;

	res = ast_safe_fork(0);
	if (res < 0) 
		ast_log(LOG_WARNING, "Fork failed\n");
	if (res) {
		return res;
	}
	if (ast_opt_high_priority)
		ast_set_priority(0);

	dup2(fd, STDOUT_FILENO);
	ast_close_fds_above_n(STDERR_FILENO);

	/* Execute mpg123, but buffer if it's a net connection */
	if (!strncasecmp(filename, "http://", 7)) {
		/* Most commonly installed in /usr/local/bin */
	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* But many places has it in /usr/bin */
	    execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* As a last-ditch effort, try to use PATH */
	    execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024",  "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
	}
	else if (strstr(filename, ".m3u")) {
		/* Most commonly installed in /usr/local/bin */
	    execl(LOCAL_MPG_123, "mpg123", "-q", "-z", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", "-@", filename, (char *)NULL);
		/* But many places has it in /usr/bin */
	    execl(MPG_123, "mpg123", "-q", "-z", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", "-@", filename, (char *)NULL);
		/* As a last-ditch effort, try to use PATH */
	    execlp("mpg123", "mpg123", "-q", "-z", "-s", "-b", "1024",  "-f", "8192", "--mono", "-r", "8000", "-@", filename, (char *)NULL);
	}
	else {
		/* Most commonly installed in /usr/local/bin */
	    execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* But many places has it in /usr/bin */
	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* As a last-ditch effort, try to use PATH */
	    execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
	}
	/* Can't use ast_log since FD's are closed */
	fprintf(stderr, "Execute of mpg123 failed\n");
	_exit(0);
}
Ejemplo n.º 8
0
static int send_waveform_to_fd(char *waveform, int length, int fd) {

        int res;
        int x;
#ifdef __PPC__ 
	char c;
#endif
	sigset_t fullset, oldset;

	sigfillset(&fullset);
	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);

        res = fork();
        if (res < 0)
                ast_log(LOG_WARNING, "Fork failed\n");
        if (res) {
		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
                return res;
	}
        for (x=0;x<256;x++) {
                if (x != fd)
                        close(x);
        }
	if (option_highpriority)
		ast_set_priority(0);
	signal(SIGPIPE, SIG_DFL);
	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
/*IAS */
#ifdef __PPC__  
	for( x=0; x<length; x+=2)
	{
		c = *(waveform+x+1);
		*(waveform+x+1)=*(waveform+x);
		*(waveform+x)=c;
	}
#endif
	
	write(fd,waveform,length);
	close(fd);
	exit(0);
}
Ejemplo n.º 9
0
static int NBScatplay(int fd)
{
	int res;

	res = ast_safe_fork(0);
	if (res < 0) {
		ast_log(LOG_WARNING, "Fork failed\n");
	}

	if (res) {
		return res;
	}

	if (ast_opt_high_priority)
		ast_set_priority(0);

	dup2(fd, STDOUT_FILENO);
	ast_close_fds_above_n(STDERR_FILENO);
	/* Most commonly installed in /usr/local/bin */
	execl(NBSCAT, "nbscat8k", "-d", (char *)NULL);
	execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL);
	fprintf(stderr, "Execute of nbscat8k failed\n");
	_exit(0);
}
Ejemplo n.º 10
0
static int mp3play(char *filename, int fd)
{
	int res;
	int x;
	res = fork();
	if (res < 0) 
		ast_log(LOG_WARNING, "Fork failed\n");
	if (res)
		return res;
	if (ast_opt_high_priority)
		ast_set_priority(0);
	dup2(fd, STDOUT_FILENO);
	for (x=0;x<256;x++) {
		if (x != STDOUT_FILENO)
			close(x);
	}
	/* Execute mpg123, but buffer if it's a net connection */
	if (!strncasecmp(filename, "http://", 7)) {
		/* Most commonly installed in /usr/local/bin */
	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* But many places has it in /usr/bin */
	    execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* As a last-ditch effort, try to use PATH */
	    execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024",  "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
	}
	else {
		/* Most commonly installed in /usr/local/bin */
	    execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* But many places has it in /usr/bin */
	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
		/* As a last-ditch effort, try to use PATH */
	    execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
	}
	ast_log(LOG_WARNING, "Execute of mpg123 failed\n");
	return -1;
}
Ejemplo n.º 11
0
static int app_exec(struct ast_channel *chan, void *data)
{
	struct ast_module_user *lu;
	struct playlist_entry *entry;
	const char *args = data;
	int child_stdin[2] = { 0,0 };
	int child_stdout[2] = { 0,0 };
	int child_stderr[2] = { 0,0 };
	int res = -1;
	int test_available_fd = -1;
	int gen_active = 0;
	int pid;
	char *argv[32];
	int argc = 1;
	char *buf, *command;
	FILE *child_commands = NULL;
	FILE *child_errors = NULL;
	FILE *child_events = NULL;
	struct ivr_localuser foo = {
		.playlist = AST_LIST_HEAD_INIT_VALUE,
		.finishlist = AST_LIST_HEAD_INIT_VALUE,
	};
	struct ivr_localuser *u = &foo;
	sigset_t fullset, oldset;

	lu = ast_module_user_add(chan);

	sigfillset(&fullset);
	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);

	u->abort_current_sound = 0;
	u->chan = chan;
	
	if (ast_strlen_zero(args)) {
		ast_log(LOG_WARNING, "ExternalIVR requires a command to execute\n");
		ast_module_user_remove(lu);
		return -1;	
	}

	buf = ast_strdupa(data);

	argc = ast_app_separate_args(buf, '|', argv, sizeof(argv) / sizeof(argv[0]));

	if (pipe(child_stdin)) {
		ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child input: %s\n", strerror(errno));
		goto exit;
	}

	if (pipe(child_stdout)) {
		ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child output: %s\n", strerror(errno));
		goto exit;
	}

	if (pipe(child_stderr)) {
		ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child errors: %s\n", strerror(errno));
		goto exit;
	}

	if (chan->_state != AST_STATE_UP) {
		ast_answer(chan);
	}

	if (ast_activate_generator(chan, &gen, u) < 0) {
		ast_chan_log(LOG_WARNING, chan, "Failed to activate generator\n");
		goto exit;
	} else
		gen_active = 1;

	pid = fork();
	if (pid < 0) {
		ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
		goto exit;
	}

	if (!pid) {
		/* child process */
		int i;

		signal(SIGPIPE, SIG_DFL);
		pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);

		if (ast_opt_high_priority)
			ast_set_priority(0);

		dup2(child_stdin[0], STDIN_FILENO);
		dup2(child_stdout[1], STDOUT_FILENO);
		dup2(child_stderr[1], STDERR_FILENO);
		for (i = STDERR_FILENO + 1; i < 1024; i++)
			close(i);
		execv(argv[0], argv);
		fprintf(stderr, "Failed to execute '%s': %s\n", argv[0], strerror(errno));
		_exit(1);
	} else {
		/* parent process */
		int child_events_fd = child_stdin[1];
		int child_commands_fd = child_stdout[0];
		int child_errors_fd = child_stderr[0];
		struct ast_frame *f;
		int ms;
		int exception;
		int ready_fd;
		int waitfds[2] = { child_errors_fd, child_commands_fd };
		struct ast_channel *rchan;

		pthread_sigmask(SIG_SETMASK, &oldset, NULL);

		close(child_stdin[0]);
		child_stdin[0] = 0;
		close(child_stdout[1]);
		child_stdout[1] = 0;
		close(child_stderr[1]);
		child_stderr[1] = 0;

		if (!(child_events = fdopen(child_events_fd, "w"))) {
			ast_chan_log(LOG_WARNING, chan, "Could not open stream for child events\n");
			goto exit;
		}

		if (!(child_commands = fdopen(child_commands_fd, "r"))) {
			ast_chan_log(LOG_WARNING, chan, "Could not open stream for child commands\n");
			goto exit;
		}

		if (!(child_errors = fdopen(child_errors_fd, "r"))) {
			ast_chan_log(LOG_WARNING, chan, "Could not open stream for child errors\n");
			goto exit;
		}

		test_available_fd = open("/dev/null", O_RDONLY);

		setvbuf(child_events, NULL, _IONBF, 0);
		setvbuf(child_commands, NULL, _IONBF, 0);
		setvbuf(child_errors, NULL, _IONBF, 0);

		res = 0;

		while (1) {
			if (ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
				ast_chan_log(LOG_NOTICE, chan, "Is a zombie\n");
				res = -1;
				break;
			}

			if (ast_check_hangup(chan)) {
				ast_chan_log(LOG_NOTICE, chan, "Got check_hangup\n");
				send_child_event(child_events, 'H', NULL, chan);
				res = -1;
				break;
			}

			ready_fd = 0;
			ms = 100;
			errno = 0;
			exception = 0;

			rchan = ast_waitfor_nandfds(&chan, 1, waitfds, 2, &exception, &ready_fd, &ms);

			if (!AST_LIST_EMPTY(&u->finishlist)) {
				AST_LIST_LOCK(&u->finishlist);
				while ((entry = AST_LIST_REMOVE_HEAD(&u->finishlist, list))) {
					send_child_event(child_events, 'F', entry->filename, chan);
					free(entry);
				}
				AST_LIST_UNLOCK(&u->finishlist);
			}

			if (rchan) {
				/* the channel has something */
				f = ast_read(chan);
				if (!f) {
					ast_chan_log(LOG_NOTICE, chan, "Returned no frame\n");
					send_child_event(child_events, 'H', NULL, chan);
					res = -1;
					break;
				}

				if (f->frametype == AST_FRAME_DTMF) {
					send_child_event(child_events, f->subclass, NULL, chan);
					if (u->option_autoclear) {
						if (!u->abort_current_sound && !u->playing_silence)
							send_child_event(child_events, 'T', NULL, chan);
						AST_LIST_LOCK(&u->playlist);
						while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list))) {
							send_child_event(child_events, 'D', entry->filename, chan);
							free(entry);
						}
						if (!u->playing_silence)
							u->abort_current_sound = 1;
						AST_LIST_UNLOCK(&u->playlist);
					}
				} else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
					ast_chan_log(LOG_NOTICE, chan, "Got AST_CONTROL_HANGUP\n");
					send_child_event(child_events, 'H', NULL, chan);
					ast_frfree(f);
					res = -1;
					break;
				}
				ast_frfree(f);
			} else if (ready_fd == child_commands_fd) {
				char input[1024];

				if (exception || feof(child_commands)) {
					ast_chan_log(LOG_WARNING, chan, "Child process went away\n");
					res = -1;
					break;
				}

				if (!fgets(input, sizeof(input), child_commands))
					continue;

				command = ast_strip(input);

				ast_chan_log(LOG_DEBUG, chan, "got command '%s'\n", input);

				if (strlen(input) < 4)
					continue;

				if (input[0] == 'S') {
					if (ast_fileexists(&input[2], NULL, u->chan->language) == -1) {
						ast_chan_log(LOG_WARNING, chan, "Unknown file requested '%s'\n", &input[2]);
						send_child_event(child_events, 'Z', NULL, chan);
						strcpy(&input[2], "exception");
					}
					if (!u->abort_current_sound && !u->playing_silence)
						send_child_event(child_events, 'T', NULL, chan);
					AST_LIST_LOCK(&u->playlist);
					while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list))) {
						send_child_event(child_events, 'D', entry->filename, chan);
						free(entry);
					}
					if (!u->playing_silence)
						u->abort_current_sound = 1;
					entry = make_entry(&input[2]);
					if (entry)
						AST_LIST_INSERT_TAIL(&u->playlist, entry, list);
					AST_LIST_UNLOCK(&u->playlist);
				} else if (input[0] == 'A') {
					if (ast_fileexists(&input[2], NULL, u->chan->language) == -1) {
						ast_chan_log(LOG_WARNING, chan, "Unknown file requested '%s'\n", &input[2]);
						send_child_event(child_events, 'Z', NULL, chan);
						strcpy(&input[2], "exception");
					}
					entry = make_entry(&input[2]);
					if (entry) {
						AST_LIST_LOCK(&u->playlist);
						AST_LIST_INSERT_TAIL(&u->playlist, entry, list);
						AST_LIST_UNLOCK(&u->playlist);
					}
				} else if (input[0] == 'H') {
					ast_chan_log(LOG_NOTICE, chan, "Hanging up: %s\n", &input[2]);
					send_child_event(child_events, 'H', NULL, chan);
					break;
				} else if (input[0] == 'O') {
					if (!strcasecmp(&input[2], "autoclear"))
						u->option_autoclear = 1;
					else if (!strcasecmp(&input[2], "noautoclear"))
						u->option_autoclear = 0;
					else
						ast_chan_log(LOG_WARNING, chan, "Unknown option requested '%s'\n", &input[2]);
				}
			} else if (ready_fd == child_errors_fd) {
				char input[1024];

				if (exception || (dup2(child_commands_fd, test_available_fd) == -1) || feof(child_errors)) {
					ast_chan_log(LOG_WARNING, chan, "Child process went away\n");
					res = -1;
					break;
				}

				if (fgets(input, sizeof(input), child_errors)) {
					command = ast_strip(input);
					ast_chan_log(LOG_NOTICE, chan, "stderr: %s\n", command);
				}
			} else if ((ready_fd < 0) && ms) { 
				if (errno == 0 || errno == EINTR)
					continue;

				ast_chan_log(LOG_WARNING, chan, "Wait failed (%s)\n", strerror(errno));
				break;
			}
		}
	}

 exit:
	if (gen_active)
		ast_deactivate_generator(chan);

	if (child_events)
		fclose(child_events);

	if (child_commands)
		fclose(child_commands);

	if (child_errors)
		fclose(child_errors);

	if (test_available_fd > -1) {
		close(test_available_fd);
	}

	if (child_stdin[0])
		close(child_stdin[0]);

	if (child_stdin[1])
		close(child_stdin[1]);

	if (child_stdout[0])
		close(child_stdout[0]);

	if (child_stdout[1])
		close(child_stdout[1]);

	if (child_stderr[0])
		close(child_stderr[0]);

	if (child_stderr[1])
		close(child_stderr[1]);

	while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list)))
		free(entry);

	ast_module_user_remove(lu);

	return res;
}
Ejemplo n.º 12
0
static pid_t spawn_ras(struct ast_channel *chan, char *args)
{
	pid_t pid;
	int x;	
	char *c;

	char *argv[PPP_MAX_ARGS];
	int argc = 0;
	char *stringp=NULL;
	sigset_t fullset, oldset;

	sigfillset(&fullset);
	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);

	/* Start by forking */
	pid = fork();
	if (pid) {
		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
		return pid;
	}

	/* Restore original signal handlers */
	for (x=0;x<NSIG;x++)
		signal(x, SIG_DFL);

	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);

	/* Execute RAS on File handles */
	dup2(chan->fds[0], STDIN_FILENO);

	/* Drop high priority */
	if (ast_opt_high_priority)
		ast_set_priority(0);

	/* Close other file descriptors */
	for (x=STDERR_FILENO + 1;x<1024;x++) 
		close(x);

	/* Reset all arguments */
	memset(argv, 0, sizeof(argv));

	/* First argument is executable, followed by standard
	   arguments for dahdi PPP */
	argv[argc++] = PPP_EXEC;
	argv[argc++] = "nodetach";

	/* And all the other arguments */
	stringp=args;
	c = strsep(&stringp, ",");
	while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
		argv[argc++] = c;
		c = strsep(&stringp, ",");
	}

	argv[argc++] = "plugin";
	argv[argc++] = "dahdi.so";
	argv[argc++] = "stdin";

	/* Finally launch PPP */
	execv(PPP_EXEC, argv);
	fprintf(stderr, "Failed to exec PPPD!\n");
	exit(1);
}