153 #include <sys/time.h>
154 #include <sys/stat.h>
155 #include <sys/mman.h>
510 #define MVM_REVIEW (1 << 0)
511 #define MVM_OPERATOR (1 << 1)
512 #define MVM_REALTIME (1 << 2)
513 #define MVM_SVMAIL (1 << 3)
514 #define MVM_ENVELOPE (1 << 4)
515 #define MVM_PBXSKIP (1 << 9)
516 #define MVM_ALLOCED (1 << 13)
520 #define SENDMAIL "/usr/sbin/sendmail -t"
522 #define SOUND_INTRO "vm-intro"
523 #define B64_BASEMAXINLINE 256
524 #define B64_BASELINELEN 72
527 #define MAX_DATETIME_FORMAT 512
528 #define MAX_NUM_CID_CONTEXTS 10
530 #define ERROR_LOCK_PATH -100
531 #define VOICEMAIL_DIR_MODE 0700
533 #define VOICEMAIL_CONFIG "minivm.conf"
534 #define ASTERISK_USERNAME "asterisk"
621 char fromaddress[100];
653 char msg_format[BUFSIZ];
666 struct timeval reset;
668 struct timeval lastreceived;
696 #define DEFAULT_DATEFORMAT "%A, %B %d, %Y at %r"
697 #define DEFAULT_CHARSET "ISO-8859-1"
710 struct minivm_template *
template;
720 ast_copy_string(template->subject,
"New message in mailbox ${MVM_USERNAME}@${MVM_DOMAIN}",
sizeof(template->subject));
721 template->attachment =
TRUE;
740 struct minivm_template *
template;
745 ast_log(
LOG_ERROR,
"Out of memory, can't allocate message template object %s.\n", name);
750 ast_debug(3,
"Configuring template option %s = \"%s\" for template %s\n", var->
name, var->
value, name);
751 if (!strcasecmp(var->
name,
"fromaddress")) {
753 }
else if (!strcasecmp(var->
name,
"fromemail")) {
755 }
else if (!strcasecmp(var->
name,
"subject")) {
757 }
else if (!strcasecmp(var->
name,
"locale")) {
759 }
else if (!strcasecmp(var->
name,
"attachmedia")) {
761 }
else if (!strcasecmp(var->
name,
"dateformat")) {
763 }
else if (!strcasecmp(var->
name,
"charset")) {
765 }
else if (!strcasecmp(var->
name,
"templatefile")) {
769 if (!template->body) {
773 }
else if (!strcasecmp(var->
name,
"messagebody")) {
777 if (!template->body) {
788 ast_log(
LOG_ERROR,
"-- %d errors found parsing message template definition %s\n", error, name);
803 struct minivm_template *
this, *res = NULL;
810 if (!strcasecmp(this->name, name)) {
825 struct minivm_template *
this;
874 if (fputs(
EOL,so) == EOF)
880 if (putc(((
unsigned char) c), so) == EOF)
897 memset(&bio, 0,
sizeof(bio));
900 if (!(fi = fopen(filename,
"rb"))) {
905 for (i= 0; i<9; i++) {
909 dtable[26+i+9]=
'j'+i;
911 for (i= 0; i < 8; i++) {
913 dtable[26+i+18]=
's'+i;
915 for (i= 0; i < 10; i++) {
922 unsigned char igroup[3], ogroup[4];
925 igroup[0]= igroup[1]= igroup[2]= 0;
927 for (n= 0; n < 3; n++) {
932 igroup[n]= (
unsigned char)c;
936 ogroup[0]= dtable[igroup[0]>>2];
937 ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)];
938 ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)];
939 ogroup[3]= dtable[igroup[2]&0x3F];
954 if (fputs(
EOL, so) == EOF)
987 static void prep_email_sub_vars(
struct ast_channel *channel,
const struct minivm_account *vmu,
const char *cidnum,
const char *cidname,
const char *dur,
const char *date,
const char *counter)
1027 struct minivm_account *
new;
1042 struct minivm_account *
this;
1054 struct minivm_account *vmu = NULL, *cur;
1061 ast_debug(3,
"Looking for voicemail user %s in domain %s\n", username, domain);
1066 if (!strcasecmp(domain, cur->domain) && !strcasecmp(username, cur->username))
1072 ast_debug(3,
"Found account for %s@%s\n", username, domain);
1078 if (createtemp && !vmu) {
1085 ast_debug(1,
"Created temporary account\n");
1099 struct minivm_account *retval;
1117 snprintf(name,
sizeof(name),
"%s@%s", username, domain);
1131 for (; *
str; str++) {
1132 if (*str > 126 || *str < 32 || strchr(
"()<>@,:;/\"[]?.=", *str)) {
1158 static const char *
ast_str_encode_mime(
struct ast_str **end, ssize_t maxlen,
const char *charset,
const char *start,
size_t preamble,
size_t postamble)
1161 int first_section = 1;
1165 for (; *start; start++) {
1166 int need_encoding = 0;
1167 if (*start < 33 || *start > 126 || strchr(
"()<>@,:;/\"[]?.=_", *start)) {
1170 if ((first_section && need_encoding && preamble +
ast_str_strlen(tmp) > 70) ||
1171 (first_section && !need_encoding && preamble +
ast_str_strlen(tmp) > 72) ||
1173 (!first_section && !need_encoding &&
ast_str_strlen(tmp) > 72)) {
1179 if (need_encoding && *start ==
' ') {
1181 }
else if (need_encoding) {
1205 for (ptr = from; *ptr; ptr++) {
1206 if (*ptr ==
'"' || *ptr ==
'\\') {
1219 static int sendmail(
struct minivm_template *
template,
struct minivm_account *vmu,
char *cidnum,
char *cidname,
const char *filename,
char *
format,
int duration,
int attach_user_voicemail,
enum mvm_messagetype type,
const char *counter)
1223 char email[256] =
"";
1227 char fname[PATH_MAX];
1229 char tmp[80] =
"/tmp/astmail-XXXXXX";
1230 char tmp2[PATH_MAX];
1231 char newtmp[PATH_MAX];
1236 char *finalfilename =
"";
1241 if (!str1 || !str2) {
1251 snprintf(email,
sizeof(email),
"%s@%s", vmu->
username, vmu->
domain);
1265 if (!strcmp(format,
"wav49"))
1271 char tmpcmd[PATH_MAX];
1276 tmpfd = mkstemp(newtmp);
1283 snprintf(tmpcmd,
sizeof(tmpcmd),
"sox -v %.4f %s.%s %s.%s", vmu->
volgain, filename, format, newtmp, format);
1286 finalfilename = newtmp;
1287 ast_debug(3,
"VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->
volgain, vmu->
username);
1293 snprintf(fname,
sizeof(fname),
"%s.%s", finalfilename, format);
1295 if (template->attachment)
1296 ast_debug(1,
"Attaching file '%s', format '%s', uservm is '%d'\n", finalfilename, format, attach_user_voicemail);
1302 p = fdopen(pfd,
"w");
1307 ast_debug(1,
"Opening temp file for e-mail: %s\n", tmp);
1323 snprintf(dur,
sizeof(dur),
"%d:%02d", duration / 60, duration % 60);
1340 ast_strftime(date,
sizeof(date),
"%a, %d %b %Y %H:%M:%S %z", &tm);
1343 fprintf(p,
"Date: %s\n", date);
1346 ast_strftime(date,
sizeof(date), template->dateformat, &tm);
1357 fromaddress =
ast_strlen_zero(template->fromaddress) ?
"" :
template->fromaddress;
1361 fromemail =
"asterisk";
1363 if (strchr(fromemail,
'@'))
1367 gethostname(host,
sizeof(host)-1);
1368 snprintf(who,
sizeof(who),
"%s@%s", fromemail, host);
1372 fprintf(p,
"From: Asterisk PBX <%s>\n", who);
1374 ast_debug(4,
"Fromaddress template: %s\n", fromaddress);
1382 fprintf(p,
"%s %s\n", first_line ?
"From:" :
"",
ast_str_buffer(str2));
1387 fprintf(p,
"%s %s <%s>\n", first_line ?
"From:" :
"",
ast_str_buffer(str2), who);
1393 fprintf(p,
"Message-ID: <Asterisk-%u-%s-%d-%s>\n", (
unsigned int)
ast_random(), vmu->
username, (
int)getpid(), who);
1396 snprintf(email,
sizeof(email),
"%s@%s", vmu->
username, vmu->
domain);
1407 fprintf(p,
"%s %s\n", first_line ?
"To:" :
"",
ast_str_buffer(str2));
1412 fprintf(p,
"%s %s <%s>\n", first_line ?
"To:" :
"",
ast_str_buffer(str2), email);
1425 fprintf(p,
"%s %s\n", first_line ?
"Subject:" :
"",
ast_str_buffer(str2));
1430 fprintf(p,
"%s %s\n", first_line ?
"Subject:" :
"",
ast_str_buffer(str2));
1435 fprintf(p,
"Subject: New message in mailbox %s@%s\n", vmu->
username, vmu->
domain);
1436 ast_debug(1,
"Using default subject for this email \n");
1440 fprintf(p,
"X-Asterisk-debug: template %s user account %s@%s\n", template->name, vmu->
username, vmu->
domain);
1441 fprintf(p,
"MIME-Version: 1.0\n");
1444 snprintf(bound,
sizeof(bound),
"voicemail_%s%d%u", vmu->
username, (
int)getpid(), (
unsigned int)
ast_random());
1446 fprintf(p,
"Content-Type: multipart/mixed; boundary=\"%s\"\n\n\n", bound);
1448 fprintf(p,
"--%s\n", bound);
1449 fprintf(p,
"Content-Type: text/plain; charset=%s\nContent-Transfer-Encoding: 8bit\n\n", template->charset);
1455 fprintf(p,
"Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message \n"
1456 "in mailbox %s from %s, on %s so you might\n"
1457 "want to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n\n", vmu->
fullname,
1458 dur, vmu->
username, (cidname ? cidname : (cidnum ? cidnum :
"an unknown caller")), date);
1459 ast_debug(3,
"Using default message body (no template)\n-----\n");
1462 if (template->attachment) {
1463 char *ctype =
"audio/x-";
1464 ast_debug(3,
"Attaching file to message: %s\n", fname);
1465 if (!strcasecmp(format,
"ogg"))
1466 ctype =
"application/";
1468 fprintf(p,
"--%s\n", bound);
1469 fprintf(p,
"Content-Type: %s%s; name=\"voicemailmsg.%s\"\n", ctype, format, format);
1470 fprintf(p,
"Content-Transfer-Encoding: base64\n");
1471 fprintf(p,
"Content-Description: Voicemail sound attachment.\n");
1472 fprintf(p,
"Content-Disposition: attachment; filename=\"voicemail%s.%s\"\n\n", counter ? counter :
"", format);
1475 fprintf(p,
"\n\n--%s--\n.\n", bound);
1478 snprintf(tmp2,
sizeof(tmp2),
"( %s < %s ; rm -f %s ) &",
global_mailcmd, tmp, tmp);
1480 ast_debug(1,
"Sent message to %s with command '%s' - %s\n", vmu->
email,
global_mailcmd, template->attachment ?
"(media attachment)" :
"");
1481 ast_debug(3,
"Actual command used: %s\n", tmp2);
1492 return snprintf(dest, len,
"%s%s/%s%s%s", MVM_SPOOL_DIR, domain, username,
ast_strlen_zero(folder) ?
"" :
"/", folder ? folder :
"");
1506 struct stat filestat;
1507 make_dir(dest, len, domain, username, folder ? folder :
"");
1508 if (stat(dest, &filestat)== -1)
1526 make_dir(dest, len, domain, username, folder);
1531 ast_debug(2,
"Creating directory for %s@%s folder %s : %s\n", username, domain, folder, dest);
1544 ast_debug(2,
"Still preparing to play message ...\n");
1546 snprintf(fn,
sizeof(fn),
"%s%s/%s/greet", MVM_SPOOL_DIR, domain, username);
1556 int numericusername = 1;
1559 ast_debug(2,
"No personal prompts. Using default prompt set for language\n");
1562 ast_debug(2,
"Numeric? Checking %c\n", *i);
1564 numericusername =
FALSE;
1570 if (numericusername) {
1600 ast_debug(1,
"Deleting voicemail file %s\n", file);
1611 int outsidecaller,
struct minivm_account *vmu,
int *duration,
int *sound_duration,
const char *unlockdir,
1612 signed char record_gain)
1615 int max_attempts = 3;
1618 int message_exists = 0;
1619 signed char zero_gain = 0;
1621 char *canceldtmf =
"";
1626 if (duration == NULL) {
1633 while ((cmd >= 0) && (cmd !=
't')) {
1636 ast_verb(3,
"Saving message as is\n");
1642 ast_verb(3,
"Reviewing the message\n");
1650 ast_verb(3,
"Re-recording the message\n");
1652 ast_verb(3,
"Recording the message\n");
1653 if (recorded && outsidecaller)
1661 cmd =
ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration,
global_silencethreshold,
global_maxsilence, unlockdir, acceptdtmf, canceldtmf);
1668 else if (cmd ==
'*')
1691 if (message_exists || recorded) {
1711 if (message_exists) {
1729 if (attempts > max_attempts) {
1744 char arguments[BUFSIZ];
1749 snprintf(arguments,
sizeof(arguments),
"%s %s@%s %s %s&",
1757 ast_debug(1,
"Executing: %s\n", arguments);
1763 static int notify_new_message(
struct ast_channel *chan,
const char *templatename,
struct minivm_account *vmu,
const char *filename,
long duration,
const char *
format,
char *cidnum,
char *cidname)
1767 char *messageformat;
1769 char oldlocale[100];
1770 const char *counter;
1792 ast_copy_string(oldlocale, setlocale(LC_TIME, NULL),
sizeof(oldlocale));
1793 ast_debug(2,
"Changing locale from %s to %s\n", oldlocale, etemplate->
locale);
1794 new_locale = setlocale(LC_TIME, etemplate->
locale);
1795 if (new_locale == NULL) {
1810 ast_debug(2,
"MVM_COUNTER not found\n");
1812 ast_debug(2,
"MVM_COUNTER found - will use it with value %s\n", counter);
1823 ast_copy_string(oldlocale, setlocale(LC_TIME,
""),
sizeof(oldlocale));
1824 setlocale(LC_TIME, etemplate->
locale);
1835 setlocale(LC_TIME, oldlocale);
1845 char tmptxtfile[PATH_MAX];
1848 int res = 0, txtdes;
1850 int sound_duration = 0;
1852 char tmpdir[PATH_MAX];
1853 char ext_context[256] =
"";
1857 struct minivm_account *vmu;
1862 domain = strchr(tmp,
'@');
1870 ast_log(
LOG_ERROR,
"Can't allocate temporary account for '%s@%s'\n", username, domain);
1876 if (strcmp(vmu->
domain,
"localhost"))
1877 snprintf(ext_context,
sizeof(ext_context),
"%s@%s", username, vmu->
domain);
1897 create_dirpath(tmpdir,
sizeof(tmpdir),
"0000_minivm_temp",
"mediafiles",
"");
1898 ast_debug(3,
"Creating temporary directory %s\n", tmpdir);
1902 snprintf(tmptxtfile,
sizeof(tmptxtfile),
"%s/XXXXXX", tmpdir);
1905 txtdes = mkstemp(tmptxtfile);
1924 ast_debug(2,
"Open file for metadata: %s\n", tmptxtfile);
1926 res =
play_record_review(chan, NULL, tmptxtfile,
global_vmmaxmessage, fmt, 1, vmu, &duration, &sound_duration, NULL, options->
record_gain);
1928 txt = fdopen(txtdes,
"w+");
1935 char logbuf[BUFSIZ];
1938 ast_strftime(timebuf,
sizeof(timebuf),
"%H:%M:%S", &tm);
1944 snprintf(logbuf,
sizeof(logbuf),
1946 "%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n",
1960 fprintf(txt,
"%s", logbuf);
1977 ast_debug(1,
"The recorded media file is gone, so we should remove the .txt file too!\n");
1987 snprintf(timebuf,
sizeof(timebuf),
"%d", duration);
1999 ast_debug(2,
"-_-_- Deleted audio file after notification :: %s \n", tmptxtfile);
2015 static void queue_mwi_event(
const char *mbx,
const char *ctx,
int urgent,
int new,
int old)
2023 context =
"default";
2061 domain = strchr(tmp,
'@');
2067 ast_log(
LOG_ERROR,
"Need mailbox@context as argument. Sorry. Argument 0 %s\n", argv[0]);
2070 queue_mwi_event(mailbox, domain, atoi(argv[1]), atoi(argv[2]), atoi(argv[3]));
2086 struct minivm_account *vmu;
2088 const char *
template =
"";
2089 const char *filename;
2091 const char *duration_string;
2105 domain = strchr(tmp,
'@');
2111 ast_log(
LOG_ERROR,
"Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]);
2117 ast_log(
LOG_WARNING,
"Could not allocate temporary memory for '%s@%s'\n", username, domain);
2167 memset(&leave_options, 0,
sizeof(leave_options));
2188 ast_log(
LOG_WARNING,
"Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
2199 ast_log(
LOG_ERROR,
"Could not leave voicemail. The path is already locked.\n");
2222 char dest[PATH_MAX];
2223 char prefile[PATH_MAX] =
"";
2224 char tempfile[PATH_MAX] =
"";
2225 char ext_context[256] =
"";
2227 char ecodes[16] =
"#";
2229 struct minivm_account *vmu;
2247 domain = strchr(tmp,
'@');
2253 ast_log(
LOG_ERROR,
"Need username@domain as argument. Sorry. Argument: %s\n", argv[0]);
2256 ast_debug(1,
"Trying to find configuration for user %s in domain %s\n", username, domain);
2268 if (strcmp(vmu->
domain,
"localhost"))
2269 snprintf(ext_context,
sizeof(ext_context),
"%s@%s", username, vmu->
domain);
2276 snprintf(prefile,
sizeof(prefile),
"%s%s/%s/busy", MVM_SPOOL_DIR, vmu->
domain, username);
2280 snprintf(prefile,
sizeof(prefile),
"%s%s/%s/unavail", MVM_SPOOL_DIR, vmu->
domain, username);
2283 snprintf(tempfile,
sizeof(tempfile),
"%s%s/%s/temp", MVM_SPOOL_DIR, vmu->
domain, username);
2285 ast_debug(2,
"Temporary message directory does not exist, using default (%s)\n", tempfile);
2288 ast_debug(2,
"Preparing to play message ...\n");
2295 strncat(ecodes,
"0",
sizeof(ecodes) - strlen(ecodes) - 1);
2300 strncat(ecodes,
"0",
sizeof(ecodes) - strlen(ecodes) - 1);
2306 strncat(ecodes,
"0",
sizeof(ecodes) - strlen(ecodes) - 1);
2314 strncat(ecodes,
"*",
sizeof(ecodes) - strlen(ecodes) - 1);
2318 strncat(ecodes,
"*",
sizeof(ecodes) - strlen(ecodes) - 1);
2322 strncat(ecodes,
"*",
sizeof(ecodes) - strlen(ecodes) - 1);
2332 ast_debug(2,
"%s doesn't exist, doing what we can\n", prefile);
2336 ast_debug(2,
"Hang up during prefile playback\n");
2361 chan->
exten[0] =
'a';
2362 chan->
exten[1] =
'\0';
2371 }
else if (res ==
'0') {
2372 if(ouseexten || ousemacro) {
2373 chan->
exten[0] =
'o';
2374 chan->
exten[1] =
'\0';
2385 }
else if (res < 0) {
2405 char filename[BUFSIZ];
2416 ast_log(
LOG_ERROR,
"No filename given in application arguments or channel variable MVM_FILENAME\n");
2425 ast_debug(2,
"Can't delete file: %s\n", filename);
2428 ast_debug(2,
"Deleted voicemail file :: %s \n", filename);
2432 ast_debug(2,
"Filename does not exist: %s\n", filename);
2444 char filename[PATH_MAX];
2447 char *tmpptr = NULL;
2448 struct minivm_account *vmu;
2458 ast_log(
LOG_ERROR,
"MinivmAccmess needs at least two arguments: account and option\n");
2466 ast_log(
LOG_ERROR,
"MinivmAccmess needs at least two arguments: account and option\n");
2469 if (!error && strlen(argv[1]) > 1) {
2470 ast_log(
LOG_ERROR,
"MinivmAccmess can only handle one option at a time. Bad option string: %s\n", argv[1]);
2486 domain = strchr(tmp,
'@');
2492 ast_log(
LOG_ERROR,
"Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]);
2499 ast_log(
LOG_WARNING,
"Could not allocate temporary memory for '%s@%s'\n", username, domain);
2511 prompt =
"vm-rec-busy";
2513 message =
"unavailable";
2514 prompt =
"vm-rec-unv";
2517 prompt =
"vm-rec-temp";
2520 prompt =
"vm-rec-name";
2522 snprintf(filename,
sizeof(filename),
"%s%s/%s/%s", MVM_SPOOL_DIR, vmu->
domain, vmu->
username, message);
2524 play_record_review(chan, prompt, filename,
global_maxgreet,
default_vmformat, 0, vmu, &duration, NULL, NULL,
FALSE);
2526 ast_debug(1,
"Recorded new %s message in %s (duration %d)\n", message, filename, duration);
2540 struct minivm_account *vmu;
2543 char accbuf[BUFSIZ];
2545 ast_debug(3,
"Creating %s account for [%s]\n", realtime ?
"realtime" :
"static", name);
2549 domain = strchr(accbuf,
'@');
2555 ast_log(
LOG_ERROR,
"No domain given for mini-voicemail account %s. Not configured.\n", name);
2559 ast_debug(3,
"Creating static account for user %s domain %s\n", username, domain);
2571 ast_debug(3,
"...Configuring account %s\n", name);
2574 ast_debug(3,
"Configuring %s = \"%s\" for account %s\n", var->
name, var->
value, name);
2575 if (!strcasecmp(var->
name,
"serveremail")) {
2577 }
else if (!strcasecmp(var->
name,
"email")) {
2579 }
else if (!strcasecmp(var->
name,
"accountcode")) {
2581 }
else if (!strcasecmp(var->
name,
"pincode")) {
2583 }
else if (!strcasecmp(var->
name,
"domain")) {
2585 }
else if (!strcasecmp(var->
name,
"language")) {
2587 }
else if (!strcasecmp(var->
name,
"timezone")) {
2589 }
else if (!strcasecmp(var->
name,
"externnotify")) {
2591 }
else if (!strcasecmp(var->
name,
"etemplate")) {
2593 }
else if (!strcasecmp(var->
name,
"ptemplate")) {
2595 }
else if (!strcasecmp(var->
name,
"fullname")) {
2597 }
else if (!strcasecmp(var->
name,
"setvar")) {
2602 if ((varval = strchr(varname,
'='))) {
2610 }
else if (!strcasecmp(var->
name,
"pager")) {
2612 }
else if (!strcasecmp(var->
name,
"volgain")) {
2615 ast_log(
LOG_ERROR,
"Unknown configuration option for minivm account %s : %s\n", name, var->
name);
2619 ast_debug(3,
"...Linking account %s\n", name);
2656 if (newzone == NULL)
2661 timezone_str =
strsep(&msg_format,
"|");
2683 char buf[BUFSIZ * 6];
2684 char readbuf[BUFSIZ];
2685 char filenamebuf[BUFSIZ];
2693 if (*filename ==
'/')
2698 if (!(fi = fopen(filenamebuf,
"r"))) {
2699 ast_log(
LOG_ERROR,
"Can't read message template from file: %s\n", filenamebuf);
2703 while (fgets(readbuf,
sizeof(readbuf), fi)) {
2705 if (writepos != buf) {
2710 writepos += strlen(readbuf) - 1;
2713 messagebody =
ast_calloc(1, strlen(buf + 1));
2715 ast_debug(4,
"---> Size of allocation %d\n", (
int) strlen(buf + 1) );
2716 ast_debug(4,
"---> Done reading message template : \n%s\n---- END message template--- \n", messagebody);
2724 char *tmpread, *tmpwrite;
2729 while ((tmpwrite = strchr(tmpread,
'\\'))) {
2730 int len = strlen(
"\n");
2731 switch (tmpwrite[1]) {
2733 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
2734 strncpy(tmpwrite,
"\n", len);
2737 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
2738 strncpy(tmpwrite,
"\t", len);
2741 ast_log(
LOG_NOTICE,
"Substitution routine does not support this character: %c\n", tmpwrite[1]);
2743 tmpread = tmpwrite +
len;
2755 if (!strcmp(var->
name,
"mailcmd")) {
2757 }
else if (!strcmp(var->
name,
"maxgreet")) {
2759 }
else if (!strcmp(var->
name,
"maxsilence")) {
2763 }
else if (!strcmp(var->
name,
"logfile")) {
2765 if(*(var->
value) ==
'/')
2770 }
else if (!strcmp(var->
name,
"externnotify")) {
2773 }
else if (!strcmp(var->
name,
"silencetreshold")) {
2776 }
else if (!strcmp(var->
name,
"maxmessage")) {
2778 if (sscanf(var->
value,
"%30d", &x) == 1) {
2784 }
else if (!strcmp(var->
name,
"minmessage")) {
2786 if (sscanf(var->
value,
"%30d", &x) == 1) {
2789 ast_log(
LOG_WARNING,
"maxsilence should be less than minmessage or you may get empty messages\n");
2794 }
else if (!strcmp(var->
name,
"format")) {
2796 }
else if (!strcmp(var->
name,
"review")) {
2798 }
else if (!strcmp(var->
name,
"operator")) {
2814 struct minivm_template *
template;
2831 ast_debug(2,
"Destroyed memory objects...\n");
2853 ast_log(
LOG_WARNING,
"Failed to load configuration file. Module activated with default settings.\n");
2858 ast_debug(2,
"Loaded configuration file, now parsing\n");
2864 ast_debug(3,
"Found configuration section [%s]\n", cat);
2865 if (!strcasecmp(cat,
"general")) {
2868 }
else if (!strncasecmp(cat,
"template-", 9)) {
2870 char *name = cat + 9;
2876 if (!strcasecmp(cat,
"zonemessages")) {
2897 ast_copy_string(template->dateformat, chanvar,
sizeof(template->dateformat));
2899 ast_copy_string(template->fromaddress, chanvar,
sizeof(template->fromaddress));
2901 ast_copy_string(template->serveremail, chanvar,
sizeof(template->serveremail));
2903 ast_copy_string(template->charset, chanvar,
sizeof(template->charset));
2905 ast_copy_string(template->subject, chanvar,
sizeof(template->subject));
2908 template->attachment =
TRUE;
2913 ast_copy_string(template->fromaddress, chanvar,
sizeof(template->fromaddress));
2915 ast_copy_string(template->serveremail, chanvar,
sizeof(template->serveremail));
2917 ast_copy_string(template->charset, chanvar,
sizeof(template->charset));
2919 ast_copy_string(template->subject, chanvar,
sizeof(template->subject));
2922 template->attachment =
FALSE;
2925 ast_log(
LOG_ERROR,
"--- A total of %d errors found in mini-voicemail configuration\n", error);
2949 struct minivm_template *
this;
2950 #define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n"
2955 e->
command =
"minivm list templates";
2957 "Usage: minivm list templates\n"
2958 " Lists message templates for e-mail, paging and IM\n";
2969 ast_cli(a->
fd,
"There are no message templates defined\n");
2977 this->charset ? this->charset :
"-",
2978 this->locale ? this->locale :
"-",
2979 this->attachment ?
"Yes" :
"No",
2980 this->subject ? this->subject :
"-");
2984 ast_cli(a->
fd,
"\n * Total: %d minivoicemail message templates\n", count);
2992 struct minivm_account *vmu;
2999 return (state == 0) ?
ast_strdup(
"for") : NULL;
3000 wordlen = strlen(word);
3002 if (!strncasecmp(word, vmu->
domain, wordlen)) {
3003 if (domain && strcmp(domain, vmu->
domain) && ++which > state)
3015 struct minivm_account *vmu;
3016 #define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n"
3021 e->
command =
"minivm list accounts";
3023 "Usage: minivm list accounts\n"
3024 " Lists all mailboxes currently set up\n";
3032 if ((a->
argc == 5) && strcmp(a->
argv[3],
"for"))
3037 ast_cli(a->
fd,
"There are no voicemail users currently defined\n");
3056 ast_cli(a->
fd,
"\n * Total: %d minivoicemail accounts\n", count);
3064 #define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n"
3069 e->
command =
"minivm list zones";
3071 "Usage: minivm list zones\n"
3072 " Lists zone message formats\n";
3089 ast_cli(a->
fd,
"There are no voicemail zones currently defined\n");
3102 e->
command =
"minivm show settings";
3104 "Usage: minivm show settings\n"
3105 " Display Mini-Voicemail general settings\n";
3111 ast_cli(a->
fd,
"* Mini-Voicemail general settings\n");
3112 ast_cli(a->
fd,
" -------------------------------\n");
3138 e->
command =
"minivm show stats";
3140 "Usage: minivm show stats\n"
3141 " Display Mini-Voicemail counters\n";
3147 ast_cli(a->
fd,
"* Mini-Voicemail statistics\n");
3148 ast_cli(a->
fd,
" -------------------------\n");
3154 ast_cli(a->
fd,
" Received messages since last reset: <none>\n");
3158 ast_strftime(buf,
sizeof(buf),
"%a %b %e %r %Z %Y", &timebuf);
3159 ast_cli(a->
fd,
" Last received voicemail: %s\n", buf);
3162 ast_strftime(buf,
sizeof(buf),
"%a %b %e %r %Z %Y", &timebuf);
3163 ast_cli(a->
fd,
" Last reset: %s\n", buf);
3172 struct minivm_account *vmu;
3177 if ((colname = strchr(username,
':'))) {
3183 if ((domain = strchr(username,
'@'))) {
3188 ast_log(
LOG_ERROR,
"This function needs a username and a domain: username@domain\n");
3195 if (!strcasecmp(colname,
"hasaccount")) {
3197 }
else if (!strcasecmp(colname,
"fullname")) {
3199 }
else if (!strcasecmp(colname,
"email")) {
3204 }
else if (!strcasecmp(colname,
"pager")) {
3206 }
else if (!strcasecmp(colname,
"etemplate")) {
3211 }
else if (!strcasecmp(colname,
"language")) {
3213 }
else if (!strcasecmp(colname,
"timezone")) {
3215 }
else if (!strcasecmp(colname,
"ptemplate")) {
3220 }
else if (!strcasecmp(colname,
"accountcode")) {
3222 }
else if (!strcasecmp(colname,
"pincode")) {
3224 }
else if (!strcasecmp(colname,
"path")) {
3230 if (!strcmp(var->
name, colname)) {
3266 char filename[BUFSIZ];
3267 char readbuf[BUFSIZ];
3269 int old = 0, counter = 0;
3275 snprintf(filename,
sizeof(filename),
"%s/%s.counter", directory, countername);
3277 counterfile = fopen(filename,
"r");
3279 if(fgets(readbuf,
sizeof(readbuf), counterfile)) {
3280 ast_debug(3,
"Read this string from counter file: %s\n", readbuf);
3281 old = counter = atoi(readbuf);
3283 fclose(counterfile);
3289 ast_debug(2,
"MINIVM Counter %s/%s: Value %d\n", directory, countername, counter);
3303 counterfile = fopen(filename,
"w");
3305 ast_log(
LOG_ERROR,
"Could not open counter file for writing : %s - %s\n", filename, strerror(
errno));
3309 fprintf(counterfile,
"%d\n\n", counter);
3310 fclose(counterfile);
3312 ast_debug(2,
"MINIVM Counter %s/%s: Old value %d New value %d\n", directory, countername, old, counter);
3320 struct minivm_account *vmu = NULL;
3321 char userpath[BUFSIZ];
3328 if ((countername = strchr(username,
':'))) {
3329 *countername =
'\0';
3333 if ((domain = strchr(username,
'@'))) {
3345 ast_log(
LOG_ERROR,
"This function needs two arguments: Account:countername\n");
3357 ast_log(
LOG_ERROR,
"Minivm account does not exist: %s@%s\n", username, domain);
3361 create_dirpath(userpath,
sizeof(userpath), domain, username, NULL);
3366 snprintf(buf, len,
"%d", res);
3374 char userpath[BUFSIZ];
3375 struct minivm_account *vmu;
3381 change = atoi(value);
3385 if ((countername = strchr(username,
':'))) {
3386 *countername =
'\0';
3389 if ((operand = strchr(countername,
':'))) {
3394 if ((domain = strchr(username,
'@'))) {
3412 ast_log(
LOG_ERROR,
"Writing to this function requires three arguments: Account:countername:operand\n");
3418 ast_log(
LOG_ERROR,
"Minivm account does not exist: %s@%s\n", username, domain);
3422 create_dirpath(userpath,
sizeof(userpath), domain, username, NULL);
3424 if (*operand ==
'i')
3426 else if (*operand ==
'd') {
3427 change = change * -1;
3429 }
else if (*operand ==
's')
3453 .
name =
"MINIVMCOUNTER",
3459 .
name =
"MINIVMACCOUNT",
3505 "Usage: minivm reload\n"
3506 " Reload mini-voicemail configuration and reset statistics\n";
3513 ast_cli(a->
fd,
"\n-- Mini voicemail re-configured \n");
#define DEFAULT_DATEFORMAT
static struct ast_app_option minivm_app_options[128]
static struct minivm_template * message_template_find(const char *name)
static int reload(void)
Reload mini voicemail module.
static int get_date(char *s, int len)
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
static int vm_delete(char *file)
#define AST_CLI_DEFINE(fn, txt,...)
char * str
Subscriber phone number (Malloced)
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
#define AST_LIST_LOCK(head)
Locks a list.
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
static char * handle_minivm_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI command to list voicemail accounts.
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf)
Record a file based on input from a channel This function will play "auth-thankyou" upon successful r...
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
static const char config[]
struct ast_party_caller caller
Channel Caller ID information.
static struct minivm_account * find_user_realtime(const char *domain, const char *username)
char * strsep(char **str, const char *delims)
static int create_vmaccount(char *name, struct ast_variable *var, int realtime)
Append new mailbox to mailbox list from configuration file.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
static struct ast_custom_function minivm_counter_function
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
static int b64_inchar(struct b64_baseio *bio, FILE *fi)
#define ast_channel_unref(c)
Decrease channel reference count.
static char * handle_minivm_list_templates(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI routine for listing templates.
static int message_template_build(const char *name, struct ast_variable *var)
#define ast_set2_flag(p, value, flag)
#define ast_test_flag(p, flag)
Time-related functions and macros.
struct ast_party_name name
Subscriber name.
Convenient Signal Processing routines.
char context[AST_MAX_CONTEXT]
static int global_vmminmessage
#define ast_set_flag(p, flag)
int ast_event_queue_and_cache(struct ast_event *event)
Queue and cache an event.
descriptor for a cli entry.
#define HMSU_OUTPUT_FORMAT
static char * handle_minivm_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Reload cofiguration.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct minivm_account *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
static int minivm_counter_func_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
${MINIVMCOUNTER()} Dialplan function - read counters
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
static void free_user(struct minivm_account *vmu)
char language[MAX_LANGUAGE]
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
int ast_unlock_path(const char *path)
Unlock a path.
mvm_messagetype
Message types for notification.
Structure for variables, used for configurations and for channel variables.
#define AST_MAX_ACCOUNT_CODE
static char * app_minivm_notify
char username[AST_MAX_CONTEXT]
static int timezone_add(const char *zonename, const char *config)
Add time zone to memory list.
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
static void vmaccounts_destroy_list(void)
Configuration File Parser.
char * str
Subscriber name (Malloced)
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
static void free_zone(struct minivm_zone *z)
Free Mini Voicemail timezone.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Number of new messages Used by: AST_EVENT_MWI Payload type: UINT.
struct ast_str * ast_str_create(size_t init_len)
Create a malloc'ed dynamic length string.
Number of Used by: AST_EVENT_MWI Payload type: UINT.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
static int global_vmmaxmessage
#define ast_mutex_lock(a)
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
#define ast_copy_flags(dest, src, flagz)
#define ast_str_alloca(init_len)
static int global_silencethreshold
static char global_mailcmd[160]
char accountcode[AST_MAX_ACCOUNT_CODE]
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
static int base_encode(char *filename, FILE *so)
static char * handle_minivm_show_zones(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Show a list of voicemail zones in the CLI.
static int minivm_mwi_exec(struct ast_channel *chan, const char *data)
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
void ast_cli(int fd, const char *fmt,...)
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
static int notify_new_message(struct ast_channel *chan, const char *templatename, struct minivm_account *vmu, const char *filename, long duration, const char *format, char *cidnum, char *cidname)
struct timeval lastreceived
static int create_dirpath(char *dest, int len, char *domain, char *username, char *folder)
int ast_unregister_application(const char *app)
Unregister an application.
#define ast_verb(level,...)
char domain[AST_MAX_CONTEXT]
void ast_config_destroy(struct ast_config *config)
Destroys a config.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int args
This gets set in ast_cli_register()
static int leave_voicemail(struct ast_channel *chan, char *username, struct leave_vm_options *options)
#define ast_manager_event(chan, category, event, contents,...)
static void message_template_free(struct minivm_template *template)
static int b64_ochar(struct b64_baseio *bio, int c, FILE *so)
Custom localtime functions for multiple timezones.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
static struct minivm_stats global_stats
Statistics for voicemail.
struct ast_party_id id
Caller party ID.
#define ast_debug(level,...)
Log a DEBUG message.
static int check_dirpath(char *dest, int len, char *domain, char *username, char *folder)
static void timezone_destroy_list(void)
Clear list of timezones.
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
enum AST_LOCK_RESULT ast_lock_path(const char *path)
Lock a filesystem path.
Context IE Used by AST_EVENT_MWI Payload type: str.
static int invent_message(struct ast_channel *chan, char *domain, char *username, int busy, char *ecodes)
static char * app_minivm_record
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
General Asterisk PBX channel definitions.
static int minivm_notify_exec(struct ast_channel *chan, const char *data)
Asterisk file paths, configured in asterisk.conf.
#define B64_BASEMAXINLINE
static int unload_module(void)
Unload mini voicemail module.
#define ast_config_load(filename, flags)
Load a config file.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Data structure associated with a custom dialplan function.
static void queue_mwi_event(const char *mbx, const char *ctx, int urgent, int new, int old)
static int global_maxgreet
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
static struct ast_cli_entry cli_minivm[]
CLI commands for Mini-voicemail.
long int ast_random(void)
A set of macros to manage forward-linked lists.
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
static char * handle_minivm_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI Show settings.
static void populate_defaults(struct minivm_account *vmu)
static char * message_template_parse_filebody(const char *filename)
Read message template from file.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
static const char * ast_str_quote(struct ast_str **buf, ssize_t maxlen, const char *from)
static struct minivm_template * message_template_create(const char *name)
Core PBX routines and definitions.
static int load_module(void)
Load mini voicemail module.
static int global_maxsilence
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
static struct minivm_account * mvm_user_alloc(void)
static FILE * minivmlogfile
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define ast_strdupa(s)
duplicate a string in memory from the stack
static char * complete_minivm_show_users(const char *line, const char *word, int pos, int state)
#define HMSZ_OUTPUT_FORMAT
static char default_vmformat[80]
static int sendmail(struct minivm_template *template, struct minivm_account *vmu, char *cidnum, char *cidname, const char *filename, char *format, int duration, int attach_user_voicemail, enum mvm_messagetype type, const char *counter)
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
struct ast_variable * chanvars
static int check_mime(const char *str)
static char * handle_minivm_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Show stats.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
unsigned char iobuf[B64_BASEMAXINLINE]
const char * ast_config_AST_CONFIG_DIR
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
enum ast_channel_state _state
const ast_string_field name
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
const char * ast_config_AST_LOG_DIR
static char * app_minivm_mwi
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define ast_channel_unlock(chan)
static int global_saydurationminfo
static ast_mutex_t minivmloglock
struct minivm_account::@47 list
char macrocontext[AST_MAX_CONTEXT]
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
static char * message_template_parse_emailbody(const char *body)
Parse emailbody template from configuration file.
const char * ast_config_AST_SPOOL_DIR
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
static char global_externnotify[160]
static struct ast_app_option minivm_accmess_options[128]
static double global_volgain
Structure used to handle boolean flags.
The list of e-mail time zones.
static int vm_lock_path(const char *path)
lock directory
Options for leaving voicemail with the voicemail() application.
Structure for base64 encoding.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
#define SENDMAIL
Default mail command to mail voicemail. Change it with the mailcmd= command in voicemail.conf.
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
The list of e-mail templates.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
static int minivm_counter_func_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
${MINIVMCOUNTER()} Dialplan function - changes counter data
static char dateformat[256]
Standard Command Line Interface.
static int load_config(int reload)
Load minivoicemail configuration.
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
#define AST_OPTION_RXGAIN
static int minivm_account_func_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
${MINIVMACCOUNT()} Dialplan function - reads account data
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
int ast_answer(struct ast_channel *chan)
Answer a channel.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
static int minivm_accmess_exec(struct ast_channel *chan, const char *data)
Record specific messages for voicemail account.
static char * app_minivm_accmess
unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
struct ast_variable * next
static const char * ast_str_encode_mime(struct ast_str **end, ssize_t maxlen, const char *charset, const char *start, size_t preamble, size_t postamble)
static int access_counter_file(char *directory, char *countername, int value, int operand)
Access counter file, lock directory, read and possibly write it again changed.
static int minivm_greet_exec(struct ast_channel *chan, const char *data)
unsigned char valid
TRUE if the name information is valid/present.
static struct ast_str * prompt
#define CONFIG_STATUS_FILEINVALID
static char context[AST_MAX_CONTEXT]
static int b64_inbuf(struct b64_baseio *bio, FILE *fi)
static char * app_minivm_greet
Structure for gathering statistics.
static void run_externnotify(struct ast_channel *chan, struct minivm_account *vmu)
Run external notification for voicemail message.
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
static ast_mutex_t minivmlock
static int make_dir(char *dest, int len, const char *domain, const char *username, const char *folder)
Say numbers and dates (maybe words one day too)
#define HVLT_OUTPUT_FORMAT
#define ASTERISK_GPL_KEY
The text the key() function should return.
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Asterisk module definitions.
static void message_destroy_list(void)
static snd_pcm_format_t format
static struct ast_flags globalflags
unsigned char valid
TRUE if the number information is valid/present.
#define ast_custom_function_register(acf)
Register a custom function.
static int minivm_record_exec(struct ast_channel *chan, const char *data)
static void prep_email_sub_vars(struct ast_channel *channel, const struct minivm_account *vmu, const char *cidnum, const char *cidname, const char *dur, const char *date, const char *counter)
const ast_string_field language
char exten[AST_MAX_EXTENSION]
#define AST_MUTEX_DEFINE_STATIC(mutex)
int ast_stopstream(struct ast_channel *c)
Stops a stream.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
static char * app_minivm_delete
static int apply_general_options(struct ast_variable *var)
Apply general configuration options.
static char mailbox[AST_MAX_EXTENSION]
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
static int minivm_delete_exec(struct ast_channel *chan, const char *data)
static char global_logfile[PATH_MAX]
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define CONFIG_STATUS_FILEUNCHANGED
#define ast_mutex_unlock(a)
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
struct ast_party_number number
Subscriber phone number.
static struct ast_custom_function minivm_account_function
static char MVM_SPOOL_DIR[PATH_MAX]