summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xapps/app_voicemail.c25
-rwxr-xr-xasterisk.c45
-rwxr-xr-xinclude/asterisk/app.h3
3 files changed, 63 insertions, 10 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 5a4196b7d..f67d03c64 100755
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -825,7 +825,7 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *m
}
fclose(p);
snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
- system(tmp2);
+ ast_safe_system(tmp2);
ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", who, mailcmd);
} else {
ast_log(LOG_WARNING, "Unable to launch '%s'\n", mailcmd);
@@ -836,16 +836,27 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *m
static int sendpage(char *srcemail, char *pager, int msgnum, char *mailbox, char *callerid, long duration, struct ast_vm_user *vmu)
{
- FILE *p;
+ FILE *p=NULL;
+ int pfd;
char date[256];
char host[256];
char who[256];
char dur[256];
+ char tmp[80] = "/tmp/astmail-XXXXXX";
+ char tmp2[256];
time_t t;
struct tm tm;
struct vm_zone *the_zone = NULL;
p = popen(mailcmd, "w");
+ if (pfd > -1) {
+ p = fdopen(pfd, "w");
+ if (!p) {
+ close(pfd);
+ pfd = -1;
+ }
+ }
+
if (p) {
gethostname(host, sizeof(host));
if (strchr(srcemail, '@'))
@@ -883,7 +894,9 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *mailbox, char
strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
fprintf(p, "New %s long msg in box %s\n"
"from %s, on %s", dur, mailbox, (callerid ? callerid : "unknown"), date);
- pclose(p);
+ fclose(p);
+ snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
+ ast_safe_system(tmp2);
ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", who, mailcmd);
} else {
ast_log(LOG_WARNING, "Unable to launch '%s'\n", mailcmd);
@@ -2296,7 +2309,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
snprintf(todir, sizeof(todir), "%s/voicemail/%s/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, vmtmp->context, vmtmp->mailbox);
snprintf(sys, sizeof(sys), "mkdir -p %s\n", todir);
ast_log(LOG_DEBUG, sys);
- system(sys);
+ ast_safe_system(sys);
todircount = count_messages(todir);
strncpy(tmp, fmt, sizeof(tmp) - 1);
@@ -2307,11 +2320,11 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
s = "WAV";
snprintf(sys, sizeof(sys), "cp %s/msg%04d.%s %s/msg%04d.%s\n", dir, curmsg, s, todir, todircount, s);
ast_log(LOG_DEBUG, sys);
- system(sys);
+ ast_safe_system(sys);
}
snprintf(sys, sizeof(sys), "cp %s/msg%04d.txt %s/msg%04d.txt\n", dir, curmsg, todir, todircount);
ast_log(LOG_DEBUG, sys);
- system(sys);
+ ast_safe_system(sys);
snprintf(fn, sizeof(fn), "%s/msg%04d", todir,todircount);
/* load the information on the source message so we can send an e-mail like a new message */
diff --git a/asterisk.c b/asterisk.c
index 2811a7cad..5e1d81215 100755
--- a/asterisk.c
+++ b/asterisk.c
@@ -28,6 +28,7 @@
#include <asterisk/pbx.h>
#include <asterisk/enum.h>
#include <asterisk/rtp.h>
+#include <asterisk/app.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <stdio.h>
@@ -153,6 +154,42 @@ static int fdprint(int fd, const char *s)
return write(fd, s, strlen(s) + 1);
}
+int ast_safe_system(const char *s)
+{
+ /* XXX This function needs some optimization work XXX */
+ pid_t pid;
+ int x;
+ int res;
+ struct rusage rusage;
+ int status;
+ pid = fork();
+ if (pid == 0) {
+ /* Close file descriptors and launch system command */
+ for (x=STDERR_FILENO + 1; x<4096;x++) {
+ close(x);
+ }
+ res = system(s);
+ exit(res);
+ } else if (pid > 0) {
+ for(;;) {
+ res = wait4(pid, &status, 0, &rusage);
+ if (res > -1) {
+ if (WIFEXITED(status))
+ res = WEXITSTATUS(status);
+ else
+ res = -1;
+ } else {
+ if (errno != EINTR)
+ break;
+ }
+ }
+ } else {
+ ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
+ res = -1;
+ }
+ return res;
+}
+
/*
* write the string to all attached console clients
*/
@@ -607,9 +644,9 @@ static void consolehandler(char *s)
/* The real handler for bang */
if (s[0] == '!') {
if (s[1])
- system(s+1);
+ ast_safe_system(s+1);
else
- system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
+ ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
} else
ast_cli_command(STDOUT_FILENO, s);
} else
@@ -627,9 +664,9 @@ static int remoteconsolehandler(char *s)
/* The real handler for bang */
if (s[0] == '!') {
if (s[1])
- system(s+1);
+ ast_safe_system(s+1);
else
- system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
+ ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
ret = 1;
}
if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) &&
diff --git a/include/asterisk/app.h b/include/asterisk/app.h
index ef7b05c27..d32575be9 100755
--- a/include/asterisk/app.h
+++ b/include/asterisk/app.h
@@ -45,6 +45,9 @@ extern int ast_app_has_voicemail(const char *mailbox);
//! Determine number of new/old messages in a mailbox
extern int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs);
+//! Safely spawn an external program while closingn file descriptors
+extern int ast_safe_system(const char *s);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif