#! /bin/sh /usr/share/dpatch/dpatch-run ## voicemail_fix_mkdir.dpatch by Tzafrir Cohen ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Fixes bad use of mkdir. Also Sets the default permissions to ## DP: voicemail files and dirs to group-accessible @DPATCH@ diff -urNad asterisk-1.0.9.dfsg.1/apps/app_voicemail.c /tmp/dpep.nwJZ0u/asterisk-1.0.9.dfsg.1/apps/app_voicemail.c --- asterisk-1.0.9.dfsg.1/apps/app_voicemail.c 2005-11-03 17:43:13.841466513 +0200 +++ /tmp/dpep.nwJZ0u/asterisk-1.0.9.dfsg.1/apps/app_voicemail.c 2005-11-03 17:45:24.625957572 +0200 @@ -63,6 +63,8 @@ #include "../astconf.h" #define COMMAND_TIMEOUT 5000 +#define VOICEMAIL_DIR_MODE 0770 +#define VOICEMAIL_FILE_MODE 0660 #define VOICEMAIL_CONFIG "voicemail.conf" #define ASTERISK_USERNAME "asterisk" @@ -699,23 +701,51 @@ ast_safe_system(buf); } -static int make_dir(char *dest, int len, char *context, char *ext, char *mailbox) +static int voicemaildir(char *dest, int len, char *context, char *ext, char *mailbox) { return snprintf(dest, len, "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR,context, ext, mailbox); } -static int make_file(char *dest, int len, char *dir, int num) +static int voicemail_file(char *dest, int len, char *dir, int num) { return snprintf(dest, len, "%s/msg%04d", dir, num); } +static int create_dirpath(char *dest, int len, char *context, char *ext, char *mailbox) +{ + mode_t mode = VOICEMAIL_DIR_MODE; + + if(context && context[0] != '\0') { + voicemaildir(dest, len, context, "", ""); + if(mkdir(dest, mode) && errno != EEXIST) { + ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno)); + return 0; + } + } + if(ext && ext[0] != '\0') { + voicemaildir(dest, len, context, ext, ""); + if(mkdir(dest, mode) && errno != EEXIST) { + ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno)); + return 0; + } + } + if(mailbox && mailbox[0] != '\0') { + voicemaildir(dest, len, context, ext, mailbox); + if(mkdir(dest, mode) && errno != EEXIST) { + ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno)); + return 0; + } + } + return 1; +} + static int last_message_index(char *dir) { int x; char fn[256]; ast_lock_path(dir); for (x=0;xmailbox, vmu->context, recip->mailbox, recip->context); - make_dir(todir, sizeof(todir), recip->context, "", ""); - /* It's easier just to try to make it than to check for its existence */ - if (mkdir(todir, 0700) && (errno != EEXIST)) - ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", todir, strerror(errno)); - make_dir(todir, sizeof(todir), recip->context, recip->mailbox, ""); - /* It's easier just to try to make it than to check for its existence */ - if (mkdir(todir, 0700) && (errno != EEXIST)) - ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", todir, strerror(errno)); - make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); - if (mkdir(todir, 0700) && (errno != EEXIST)) - ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", todir, strerror(errno)); + create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); - make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); - make_file(frompath, sizeof(frompath), fromdir, msgnum); + voicemaildir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); + voicemail_file(frompath, sizeof(frompath), fromdir, msgnum); ast_lock_path(topath); recipmsgnum = 0; do { - make_file(topath, sizeof(topath), todir, recipmsgnum); + voicemail_file(topath, sizeof(topath), todir, recipmsgnum); if (ast_fileexists(topath, NULL, chan->language) <= 0) break; recipmsgnum++; @@ -1342,17 +1362,7 @@ snprintf(prefile, sizeof(prefile), "voicemail/%s/%s/busy", vmu->context, ext); else if (unavail) snprintf(prefile, sizeof(prefile), "voicemail/%s/%s/unavail", vmu->context, ext); - make_dir(dir, sizeof(dir), vmu->context, "", ""); - /* It's easier just to try to make it than to check for its existence */ - if (mkdir(dir, 0700) && (errno != EEXIST)) - ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); - make_dir(dir, sizeof(dir), vmu->context, ext, ""); - /* It's easier just to try to make it than to check for its existence */ - if (mkdir(dir, 0700) && (errno != EEXIST)) - ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); - make_dir(dir, sizeof(dir), vmu->context, ext, "INBOX"); - if (mkdir(dir, 0700) && (errno != EEXIST)) - ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); + create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); /* Check current or macro-calling context for special extensions */ if (!ast_strlen_zero(vmu->exit)) { @@ -1454,7 +1464,7 @@ } ast_lock_path(dir); do { - make_file(fn, sizeof(fn), dir, msgnum); + voicemail_file(fn, sizeof(fn), dir, msgnum); if (ast_fileexists(fn, NULL, chan->language) <= 0) break; msgnum++; @@ -1582,11 +1592,11 @@ ast_lock_path(dir); for (x=0,dest=0;x 0) { if(x != dest) { - make_file(dfn, sizeof(dfn), dir, dest); + voicemail_file(dfn, sizeof(dfn), dir, dest); ast_filerename(sfn,dfn,NULL); snprintf(stxt, sizeof(stxt), "%s.txt", sfn); @@ -1617,12 +1627,11 @@ char ntxt[256]; char *dbox = mbox(box); int x; - make_file(sfn, sizeof(sfn), dir, msg); - make_dir(ddir, sizeof(ddir), context, username, dbox); - mkdir(ddir, 0700); + voicemail_file(sfn, sizeof(sfn), dir, msg); + create_dirpath(ddir, sizeof(ddir), context, username, dbox); ast_lock_path(ddir); for (x=0;xcontext, vmu->mailbox, "INBOX"); - make_file(fn, sizeof(fn), todir, msgnum); + voicemaildir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX"); + voicemail_file(fn, sizeof(fn), todir, msgnum); snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); /* Attach only the first format */ @@ -2326,11 +2335,8 @@ /* if (ast_play_and_wait(chan, "vm-savedto")) break; */ - 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); + create_dirpath(todir, sizeof(todir), vmtmp->context, vmtmp->mailbox, "INBOX"); snprintf(ext_context, sizeof(ext_context), "%s@%s", vmtmp->mailbox, vmtmp->context); - ast_log(LOG_DEBUG, "%s", sys); - ast_safe_system(sys); todircount = count_messages(todir); strncpy(tmp, fmt, sizeof(tmp) - 1); @@ -2548,7 +2554,7 @@ struct ast_config *msg_cfg; vms->starting = 0; - make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); + voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); adsi_message(chan, vms); if (!vms->curmsg) res = wait_file2(chan, vms, "vm-first"); /* "First" */ @@ -2563,7 +2569,7 @@ } /* Retrieve info from VM attribute file */ - make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); + voicemail_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); snprintf(filename,sizeof(filename), "%s.txt", vms->fn2); msg_cfg = ast_load(filename); if (!msg_cfg) { @@ -2590,7 +2596,7 @@ ast_destroy(msg_cfg); if (!res) { - make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); + voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); vms->heard[vms->curmsg] = 1; res = wait_file(chan, vms, vms->fn); } @@ -2600,7 +2606,7 @@ static void open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box) { strncpy(vms->curbox, mbox(box), sizeof(vms->curbox) - 1); - make_dir(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); + voicemaildir(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); vms->lastmsg = count_messages(vms->curdir) - 1; /* @@ -2631,11 +2637,11 @@ for (x=0;x < MAXMSG;x++) { if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { /* Save this message. It's not in INBOX or hasn't been heard */ - make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); + voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, x); if (ast_fileexists(vms->fn, NULL, NULL) < 1) break; vms->curmsg++; - make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); + voicemail_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); if (strcmp(vms->fn, vms->fn2)) { snprintf(txt, sizeof(txt), "%s.txt", vms->fn); snprintf(ntxt, sizeof(ntxt), "%s.txt", vms->fn2); @@ -2648,7 +2654,7 @@ } } for (x = vms->curmsg + 1; x <= MAXMSG; x++) { - make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); + voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, x); if (ast_fileexists(vms->fn, NULL, NULL) < 1) break; vm_delete(vms->fn); @@ -3489,10 +3495,7 @@ /* Set language from config to override channel language */ if (vmu->language && !ast_strlen_zero(vmu->language)) strncpy(chan->language, vmu->language, sizeof(chan->language)-1); - snprintf(vms.curdir, sizeof(vms.curdir), "%s/voicemail/%s", (char *)ast_config_AST_SPOOL_DIR, vmu->context); - mkdir(vms.curdir, 0700); - snprintf(vms.curdir, sizeof(vms.curdir), "%s/voicemail/%s/%s", (char *)ast_config_AST_SPOOL_DIR, vmu->context, vms.username); - mkdir(vms.curdir, 0700); + create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, ""); /* Retrieve old and new message counts */ open_mailbox(&vms, vmu, 1); vms.oldmessages = vms.lastmsg + 1; @@ -3687,7 +3690,7 @@ cmd = save_to_folder(vms.curdir, vms.curmsg, vmu->context, vms.username, cmd); vms.deleted[vms.curmsg]=1; } - make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); + voicemail_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); if (useadsi) adsi_message(chan, &vms); if (!cmd) @@ -3922,7 +3925,7 @@ char count[12]; if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) { - make_dir(dirname, 255, vmu->context, vmu->mailbox, "INBOX"); + voicemaildir(dirname, 255, vmu->context, vmu->mailbox, "INBOX"); if ((vmdir = opendir(dirname))) { /* No matter what the format of VM, there will always be a .txt file for each message. */ while ((vment = readdir(vmdir))) @@ -4498,11 +4501,11 @@ int retries = 0; vms->starting = 0; - make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); + voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); /* Retrieve info from VM attribute file */ - make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); + voicemail_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); snprintf(filename,sizeof(filename), "%s.txt", vms->fn2); msg_cfg = ast_load(filename); if (!msg_cfg) { @@ -4638,7 +4641,7 @@ ast_destroy(msg_cfg); if (!res) { - make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); + voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); vms->heard[msg] = 1; res = wait_file(chan, vms, vms->fn); }