Index: file.c =================================================================== RCS file: /usr/cvsroot/asterisk/file.c,v retrieving revision 1.40 diff -u -r1.40 file.c --- file.c 21 Apr 2004 03:53:15 -0000 1.40 +++ file.c 3 May 2004 02:05:35 -0000 @@ -240,6 +240,11 @@ int res; int len; char buf[4096]; + + /* A hard link is always faster, but there are reasons why a hard link might not succeed */ + if (link(infile, outfile) == 0) + return 0; + if ((ifd = open(infile, O_RDONLY)) < 0) { ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile); return -1; @@ -342,6 +347,9 @@ /* Try each kind of extension */ stringp=exts; ext = strsep(&stringp, "|"); + if (!strcmp(ext,"wav49")) { + ext = "WAV"; + } do { fn = build_filename(filename, ext); if (fn) { Index: apps/app_voicemail.c =================================================================== RCS file: /usr/cvsroot/asterisk/apps/app_voicemail.c,v retrieving revision 1.86 diff -u -r1.86 app_voicemail.c --- apps/app_voicemail.c 1 May 2004 23:28:33 -0000 1.86 +++ apps/app_voicemail.c 3 May 2004 02:05:39 -0000 @@ -110,7 +110,9 @@ char zonetag[80]; char callback[80]; char dialout[80]; + char msg_cc[255]; int attach; + int delete; int alloced; int saycid; int review; @@ -278,6 +280,10 @@ strncpy(vmu->serveremail, value, sizeof(vmu->serveremail) - 1); } else if (!strcasecmp(var, "tz")) { strncpy(vmu->zonetag, value, sizeof(vmu->zonetag) - 1); + } else if (!strcasecmp(var, "cc")) { + strncpy(vmu->msg_cc, value, sizeof(vmu->msg_cc) - 1); + } else if (!strcasecmp(var, "delete")) { + vmu->delete = ast_true(value); } else if (!strcasecmp(var, "saycid")){ if(ast_true(value)) vmu->saycid = 1; @@ -297,7 +303,6 @@ strncpy(vmu->callback, value, sizeof(vmu->callback) -1); } else if (!strcasecmp(var, "dialout")) { strncpy(vmu->dialout, value, sizeof(vmu->dialout) -1); - } } } @@ -1471,6 +1476,36 @@ free(z); } +static char *mbox(int id) +{ + switch(id) { + case 0: + return "INBOX"; + case 1: + return "Old"; + case 2: + return "Work"; + case 3: + return "Family"; + case 4: + return "Friends"; + case 5: + return "Cust1"; + case 6: + return "Cust2"; + case 7: + return "Cust3"; + case 8: + return "Cust4"; + case 9: + return "Cust5"; + default: + return "Unknown"; + } +} + +static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, char *fmt, char *callerid, int recursive); + static void run_externnotify(char *context, char *extension, int numvoicemails) { char arguments[255]; @@ -1486,7 +1521,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int busy, int unavail) { - char comment[256]; char txtfile[256]; FILE *txt; int res = 0; @@ -1598,9 +1632,6 @@ msgnum = 0; do { make_file(fn, sizeof(fn), dir, msgnum); - snprintf(comment, sizeof(comment), "Voicemail from %s to %s (%s) on %s\n", - (chan->callerid ? chan->callerid : "Unknown"), - vmu->fullname, ext, chan->name); if (ast_fileexists(fn, NULL, chan->language) <= 0) break; msgnum++; @@ -1656,22 +1687,8 @@ } stringp = fmt; strsep(&stringp, "|"); - /* Send e-mail if applicable */ - if (strlen(vmu->email)) { - int attach_user_voicemail = attach_voicemail; - char *myserveremail = serveremail; - if (vmu->attach > -1) - attach_user_voicemail = vmu->attach; - if (strlen(vmu->serveremail)) - myserveremail = vmu->serveremail; - sendmail(myserveremail, vmu, msgnum, ext, chan->callerid, fn, fmt, duration, attach_user_voicemail); - } - if (strlen(vmu->pager)) { - char *myserveremail = serveremail; - if (strlen(vmu->serveremail)) - myserveremail = vmu->serveremail; - sendpage(myserveremail, vmu->pager, msgnum, ext, chan->callerid, duration, vmu); - } + + notify_new_message(chan, vmu, msgnum, fmt, chan->callerid, 0); } else { res = ast_streamfile(chan, "vm-mailboxfull", chan->language); if (!res) @@ -1679,7 +1696,7 @@ ast_log(LOG_WARNING, "No more messages possible\n"); } } else - ast_log(LOG_WARNING, "No format for saving voicemail?\n"); + ast_log(LOG_WARNING, "No format for saving voicemail?\n"); leave_vm_out: free_user(vmu); } else { @@ -1688,43 +1705,10 @@ if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid)) chan->priority+=100; } - /* Leave voicemail for someone */ - manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext, ast_app_has_voicemail(ext)); - - /* If an external program is specified to be run after leaving a voicemail */ - run_externnotify(chan->context, ext, ast_app_has_voicemail(ext)); return res; } -static char *mbox(int id) -{ - switch(id) { - case 0: - return "INBOX"; - case 1: - return "Old"; - case 2: - return "Work"; - case 3: - return "Family"; - case 4: - return "Friends"; - case 5: - return "Cust1"; - case 6: - return "Cust2"; - case 7: - return "Cust3"; - case 8: - return "Cust4"; - case 9: - return "Cust5"; - default: - return "Unknown"; - } -} - static int count_messages(char *dir) { int x; @@ -1811,6 +1795,19 @@ return 0; } +static void copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, struct ast_vm_user *recip, char *fmt) +{ + char fromdir[256], frompath[256]; + char *frombox = mbox(imbox); + + make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); + make_file(frompath, sizeof(frompath), fromdir, msgnum); + save_to_folder(fromdir, msgnum, recip->context, recip->mailbox, 0); + + /* Groups may not contain groups */ + notify_new_message(chan, recip, ast_app_has_voicemail(recip->mailbox), fmt, chan->callerid, 1); +} + static int adsi_logo(unsigned char *buf) { int bytes = 0; @@ -2379,6 +2376,114 @@ return cmd; } +static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, char *fmt, char *callerid, int recursive) +{ + char todir[256], fn[256], miffile[256], *s; + struct ast_config *mif; + long duration; + + /* load the information on the source message so we can send an e-mail like a new message */ + make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX"); + make_file(fn, sizeof(fn), todir, msgnum); + snprintf(miffile, sizeof(miffile), "%s.txt", fn); + if ((mif=ast_load(miffile))) { + + s = ast_variable_retrieve(mif, NULL, "duration"); + if (s) + duration = atol(s); + else + duration = 0; + + if (strlen(vmu->email)) { + int attach_user_voicemail = attach_voicemail; + char *myserveremail = serveremail; + if (vmu->attach > -1) + attach_user_voicemail = vmu->attach; + if (strlen(vmu->serveremail)) + myserveremail = vmu->serveremail; + sendmail(myserveremail, vmu, msgnum, vmu->mailbox, callerid, fn, fmt, duration, attach_user_voicemail); + } + + if (strlen(vmu->pager)) { + char *myserveremail = serveremail; + if (strlen(vmu->serveremail)) + myserveremail = vmu->serveremail; + sendpage(myserveremail, vmu->pager, msgnum, vmu->mailbox, callerid, duration, vmu); + } + + if ((!recursive) && strlen(vmu->msg_cc)) { + /* We have multiple ways to specify recipients: + * a. 1234 Single mailbox + * b. 1234@context Single mailbox in non-default context + * c. *@context All mailboxes in a context + * d. * All mailboxes on the system + */ + char *cc = ast_strdupa(vmu->msg_cc); + + if (cc) { + char *recipient; + while ((recipient = strsep(&cc, ";"))) { + char *ccbox = strsep(&recipient, "@"); + if (ccbox && *ccbox) { + struct ast_vm_user *recip; + if (*ccbox == '*') { + if ((!recipient) || (!*recipient)) { + /* All users on system */ + ast_mutex_lock(&vmlock); + recip = users; + while (recip) { + /* Don't copy to self */ + if (strcmp(vmu->context, recip->context) || strcmp(vmu->mailbox, recip->mailbox)) { + copy_message(chan, vmu, 0, msgnum, recip, fmt); + } + recip = recip->next; + } + ast_mutex_unlock(&vmlock); + } else { + /* All users in particular context */ + ast_mutex_lock(&vmlock); + recip = users; + while (recip) { + if (!strcmp(recip->context, recipient)) + copy_message(chan, vmu, 0, msgnum, recip, fmt); + recip = recip->next; + } + ast_mutex_unlock(&vmlock); + } + } else { + /* Single mailbox */ + if ((!recipient) || (!*recipient)) { + recip = find_user(NULL, "default", ccbox); + } else { + recip = find_user(NULL, recipient, ccbox); + } + if (recip) { + copy_message(chan, vmu, 0, msgnum, recip, fmt); + free(recip); + } + } + } else { + ast_log(LOG_ERROR, "Incorrectly specified CC: '@%s' (should be |*[@context])\n", recipient); + } + } + } else { + ast_log(LOG_ERROR, "Out of memory\n"); + } + } + + if (vmu->delete) { + ast_filedelete(fn, NULL); + unlink(miffile); + } + + ast_destroy(mif); /* or here */ + } + /* Leave voicemail for someone */ + manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", vmu->mailbox, ast_app_has_voicemail(vmu->mailbox)); + run_externnotify(chan->context, vmu->mailbox, ast_app_has_voicemail(vmu->mailbox)); + return 0; +} + static int forward_message(struct ast_channel *chan, char *context, char *dir, int curmsg, struct ast_vm_user *sender, char *fmt) { char username[70];