56#include <imap/c-client.h> 
   57#include <imap/imap4r1.h> 
   58#include <imap/linkage.h> 
   59#elif defined (USE_SYSTEM_CCLIENT) 
   60#include <c-client/c-client.h> 
   61#include <c-client/imap4r1.h> 
   62#include <c-client/linkage.h> 
   76#if defined(__FreeBSD__) || defined(__OpenBSD__) 
  616static char imapserver[48] = 
"localhost";
 
  617static char imapport[8] = 
"143";
 
  618static char imapflags[128];
 
  619static char imapfolder[64] = 
"INBOX";
 
  620static char imapparentfolder[64];
 
  621static char greetingfolder[64] = 
"INBOX";
 
  622static char authuser[32];
 
  623static char authpassword[42];
 
  624static int imapversion = 1;
 
  626static int expungeonhangup = 1;
 
  627static int imapgreetings;
 
  628static int imap_poll_logout;
 
  629static char delimiter;
 
  640static int init_mailstream(
struct vm_state *vms, 
int box);
 
  641static void write_file(
char *filename, 
char *buffer, 
unsigned long len);
 
  642static char *get_header_by_tag(
char *
header, 
char *tag, 
char *
buf, 
size_t len);
 
  643static void vm_imap_delete(
char *file, 
int msgnum, 
struct ast_vm_user *vmu);
 
  644static char *get_user_by_mailbox(
char *
mailbox, 
char *
buf, 
size_t len);
 
  645static struct vm_state *get_vm_state_by_imapuser(
const char *
user, 
int interactive);
 
  646static struct vm_state *get_vm_state_by_mailbox(
const char *mailbox, 
const char *
context, 
int interactive);
 
  648static void vmstate_insert(
struct vm_state *vms);
 
  649static void vmstate_delete(
struct vm_state *vms);
 
  650static void set_update(MAILSTREAM * stream);
 
  651static void init_vm_state(
struct vm_state *vms);
 
  652static int save_body(BODY *body, 
struct vm_state *vms, 
char *section, 
char *format, 
int is_intro);
 
  653static void get_mailbox_delimiter(
struct vm_state *vms, MAILSTREAM *stream);
 
  654static void mm_parsequota (MAILSTREAM *stream, 
unsigned char *msg, QUOTALIST *pquota);
 
  655static void imap_mailbox_name(
char *spec, 
size_t len, 
struct vm_state *vms, 
int box, 
int target);
 
  656static int imap_store_file(
const char *dir, 
const char *mailboxuser, 
const char *mailboxcontext, 
int msgnum, 
struct ast_channel *chan, 
struct ast_vm_user *vmu, 
char *fmt, 
int duration, 
struct vm_state *vms, 
const char *
flag, 
const char *msg_id);
 
  657static void vm_imap_update_msg_id(
char *dir, 
int msgnum, 
const char *msg_id, 
struct ast_vm_user *vmu, 
struct ast_config *msg_cfg, 
int folder);
 
  658static void update_messages_by_imapuser(
const char *
user, 
unsigned long number);
 
  661static int imap_remove_file (
char *dir, 
int msgnum);
 
  662static int imap_retrieve_file (
const char *dir, 
const int msgnum, 
const char *mailbox, 
const char *
context);
 
  663static int imap_delete_old_greeting (
char *dir, 
struct vm_state *vms);
 
  664static void check_quota(
struct vm_state *vms, 
char *mailbox);
 
  666static void imap_logout(
const char *mailbox_id);
 
  677#define SMDI_MWI_WAIT_TIMEOUT 1000  
  679#define COMMAND_TIMEOUT 5000 
  681#define VOICEMAIL_DIR_MODE  0777 
  682#define VOICEMAIL_FILE_MODE 0666 
  683#define CHUNKSIZE   65536 
  685#define VOICEMAIL_CONFIG "voicemail.conf" 
  686#define ASTERISK_USERNAME "asterisk" 
  691#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" 
  692#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" 
  693#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" 
  694#define DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" 
  695#define DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" 
  696#define VALID_DTMF "1234567890*#"  
  700#define SENDMAIL "/usr/sbin/sendmail -t" 
  701#define INTRO "vm-intro" 
  703#define MAX_MAIL_BODY_CONTENT_SIZE 134217728L  
  706#define MAXMSGLIMIT 9999 
  716#define MAX_DATETIME_FORMAT 512 
  717#define MAX_NUM_CID_CONTEXTS 10 
  719#define VM_REVIEW        (1 << 0)    
  720#define VM_OPERATOR      (1 << 1)    
  721#define VM_SAYCID        (1 << 2)    
  722#define VM_SVMAIL        (1 << 3)    
  723#define VM_ENVELOPE      (1 << 4)    
  724#define VM_SAYDURATION   (1 << 5)    
  725#define VM_SKIPAFTERCMD  (1 << 6)    
  726#define VM_FORCENAME     (1 << 7)    
  727#define VM_FORCEGREET    (1 << 8)    
  728#define VM_PBXSKIP       (1 << 9)    
  729#define VM_DIRECTFORWARD (1 << 10)   
  730#define VM_ATTACH        (1 << 11)   
  731#define VM_DELETE        (1 << 12)   
  732#define VM_ALLOCED       (1 << 13)   
  733#define VM_SEARCH        (1 << 14)   
  734#define VM_TEMPGREETWARN (1 << 15)   
  735#define VM_MOVEHEARD     (1 << 16)   
  736#define VM_MESSAGEWRAP   (1 << 17)   
  737#define VM_FWDURGAUTO    (1 << 18)   
  738#define VM_EMAIL_EXT_RECS (1 << 19)   
  739#define VM_MARK_URGENT   (1 << 20)   
  740#define VM_ODBC_AUDIO_ON_DISK  (1 << 21)  
  742#define ERROR_LOCK_PATH  -100 
  743#define ERROR_MAX_MSGS   -101 
  744#define OPERATOR_EXIT     300 
  746#define MSGFILE_LEN (7)  
  832#define force_reload_config() load_config_force(1, 1) 
  932#define MAX_VM_MBOX_ID_LEN (AST_MAX_EXTENSION) 
  933#define MAX_VM_CONTEXT_LEN (AST_MAX_CONTEXT) 
  935#define MAX_VM_MAILBOX_LEN (MAX_VM_MBOX_ID_LEN + MAX_VM_CONTEXT_LEN) 
  970    char imappassword[80];           
 
  972    char imapvmshareid[80];          
 
 
  987#define VMSTATE_MAX_MSG_ARRAY 256 
 1012    unsigned msg_array_max;
 
 1013    MAILSTREAM *mailstream;
 
 1016    char imapfolder[64];                 
 
 1017    char imapserver[48];                 
 
 1019    char imapflags[128];                 
 
 1023    unsigned int quota_limit;
 
 1024    unsigned int quota_usage;
 
 
 1030static char odbc_database[80] = 
"asterisk";
 
 1031static char odbc_table[80] = 
"voicemessages";
 
 1032size_t odbc_table_len = 
sizeof(odbc_table);
 
 1033#define COUNT(a, b) odbc_count_messages(a,b) 
 1034#define LAST_MSG_INDEX(a) odbc_last_message_index(a) 
 1035#define RETRIEVE(a,b,c,d) odbc_retrieve_message(a,b) 
 1036#define DISPOSE(a,b) odbc_remove_files(a,b) 
 1037#define STORE(a,b,c,d,e,f,g,h,i,j,k) odbc_store_message(a,b,c,d) 
 1038#define EXISTS(a,b,c,d) (odbc_message_exists(a,b)) 
 1039#define RENAME(a,b,c,d,e,f,g,h) (odbc_rename_message(a,b,c,d,e,f)) 
 1040#define COPY(a,b,c,d,e,f,g,h) (odbc_copy_message(a,b,c,d,e,f)) 
 1041#define DELETE(a,b,c,d) (odbc_delete_message(a,b)) 
 1042#define UPDATE_MSG_ID(a, b, c, d, e, f) (odbc_update_msg_id((a), (b), (c))) 
 1045#define DISPOSE(a,b) (imap_remove_file(a,b)) 
 1046#define STORE(a,b,c,d,e,f,g,h,i,j,k) (imap_store_file(a,b,c,d,e,f,g,h,i,j,k)) 
 1047#define RETRIEVE(a,b,c,d) imap_retrieve_file(a,b,c,d) 
 1048#define EXISTS(a,b,c,d) (ast_fileexists(c,NULL,d) > 0) 
 1049#define RENAME(a,b,c,d,e,f,g,h) (rename_file(g,h)); 
 1050#define COPY(a,b,c,d,e,f,g,h) (copy_file(g,h)); 
 1051#define DELETE(a,b,c,d) (vm_imap_delete(a,b,d)) 
 1052#define UPDATE_MSG_ID(a, b, c, d, e, f) (vm_imap_update_msg_id((a), (b), (c), (d), (e), (f))) 
 1054#define COUNT(a, b) count_messages(a,b) 
 1055#define LAST_MSG_INDEX(a) last_message_index(a) 
 1056#define RETRIEVE(a,b,c,d) 
 1058#define STORE(a,b,c,d,e,f,g,h,i,j,k) 
 1059#define EXISTS(a,b,c,d) (ast_fileexists(c,NULL,d) > 0) 
 1060#define RENAME(a,b,c,d,e,f,g,h) (rename_file(g,h)); 
 1061#define COPY(a,b,c,d,e,f,g,h) (copy_plain_file(g,h)); 
 1062#define DELETE(a,b,c,d) (vm_delete(c)) 
 1063#define UPDATE_MSG_ID(a, b, c, d, e, f) 
 1074#define PWDCHANGE_INTERNAL (1 << 1) 
 1075#define PWDCHANGE_EXTERNAL (1 << 2) 
 1079#define tdesc "Comedian Mail (Voicemail System) with ODBC Storage" 
 1082# define tdesc "Comedian Mail (Voicemail System) with IMAP Storage" 
 1084# define tdesc "Comedian Mail (Voicemail System)" 
 1130#define DEFAULT_POLL_FREQ 30 
 1153#define MAPPING_BUCKETS 511 
 1211static unsigned char adsifdn[4] = 
"\x00\x00\x00\x0F";
 
 1212static unsigned char adsisec[4] = 
"\x9B\xDB\xF7\xAC";
 
 1223            char *fmt, 
int outsidecaller, 
struct ast_vm_user *vmu, 
int *duration, 
int *sound_duration, 
const char *unlockdir,
 
 1224            signed char record_gain, 
struct vm_state *vms, 
char *
flag, 
const char *msg_id, 
int forwardintro);
 
 1228static void make_email_file(FILE *p, 
char *srcemail, 
struct ast_vm_user *vmu, 
int msgnum, 
char *context, 
char *mailbox, 
const char *fromfolder, 
char *cidnum, 
char *cidname, 
char *attach, 
char *attach2, 
char *format, 
int duration, 
int attach_user_voicemail, 
struct ast_channel *chan, 
const char *category, 
int imap, 
const char *
flag, 
const char *msg_id);
 
 1230static int add_email_attachment(FILE *p, 
struct ast_vm_user *vmu, 
char *format, 
char *attach, 
char *greeting_attachment, 
char *mailbox, 
char *bound, 
char *filename, 
int last, 
int msgnum);
 
 1260static int vm_msg_forward(
const char *from_mailbox, 
const char *from_context, 
const char *from_folder, 
const char *to_mailbox, 
const char *to_context, 
const char *to_folder, 
size_t num_msgs, 
const char *msg_ids[], 
int delete_old);
 
 1261static int vm_msg_move(
const char *mailbox, 
const char *context, 
size_t num_msgs, 
const char *oldfolder, 
const char *old_msg_ids[], 
const char *newfolder);
 
 1262static int vm_msg_remove(
const char *mailbox, 
const char *context, 
size_t num_msgs, 
const char *folder, 
const char *msgs[]);
 
 1265#ifdef TEST_FRAMEWORK 
 1266static int vm_test_destroy_user(
const char *context, 
const char *mailbox);
 
 1267static int vm_test_create_user(
const char *context, 
const char *mailbox);
 
 1287    *context = mailbox_id;
 
 1288    *mailbox = 
strsep(context, 
"@");
 
 1293        *context = 
"default";
 
 
 1315    if (strcmp(i->
mailbox, j->mailbox)) {
 
 
 1323    int context_len = strlen(
context) + 1;
 
 1324    int mailbox_len = strlen(
mailbox) + 1;
 
 1339    if (!(i = 
ao2_alloc(
sizeof(*i) + context_len + mailbox_len, 
NULL))) {
 
 
 1353#if !(defined(ODBC_STORAGE) || defined(IMAP_STORAGE)) 
 1366    for (; *input; input++) {
 
 1371        if (bufptr == 
buf + buflen - 1) {
 
 
 1398static size_t get_msg_path_len(
const char *dir)
 
 1412#define MAX_SOUND_EXTEN_LEN 12 
 1425static size_t get_msg_path_ext_len(
const char *dir)
 
 1431    return strlen(dir) + 1 + 
MSGFILE_LEN + MAX_SOUND_EXTEN_LEN + 1;
 
 1455#define MAKE_FILE_PTRA(dir, msgnum) \ 
 1457    size_t __len = get_msg_path_len(dir); \ 
 1460        __var = ast_strdupa(dir); \ 
 1462        __var = ast_alloca(__len); \ 
 1463        snprintf(__var, __len, "%s/msg%04d", dir, msgnum); \ 
 1497#define MAKE_FILE_EXT_PTRA(dir, msgnum, ext) \ 
 1499    size_t __len = get_msg_path_ext_len(dir); \ 
 1500    char *__var = ast_alloca(__len); \ 
 1502        snprintf(__var, __len, "%s.%s", dir, ext); \ 
 1504        snprintf(__var, __len, "%s/msg%04d.%s", dir, msgnum, ext); \ 
 1555    ast_copy_string(vmu->imapfolder, imapfolder, 
sizeof(vmu->imapfolder));
 
 1556    ast_copy_string(vmu->imapserver, imapserver, 
sizeof(vmu->imapserver));
 
 
 1573    if (!strcasecmp(
var, 
"attach")) {
 
 1575    } 
else if (!strcasecmp(
var, 
"attachfmt")) {
 
 1577    } 
else if (!strcasecmp(
var, 
"attachextrecs")) {
 
 1579    } 
else if (!strcasecmp(
var, 
"serveremail")) {
 
 1581    } 
else if (!strcasecmp(
var, 
"fromstring")) {
 
 1583    } 
else if (!strcasecmp(
var, 
"emailbody")) {
 
 1586    } 
else if (!strcasecmp(
var, 
"emailsubject")) {
 
 1589    } 
else if (!strcasecmp(
var, 
"language")) {
 
 1591    } 
else if (!strcasecmp(
var, 
"tz")) {
 
 1593    } 
else if (!strcasecmp(
var, 
"locale")) {
 
 1596    } 
else if (!strcasecmp(
var, 
"imapuser")) {
 
 1598        vmu->imapversion = imapversion;
 
 1599    } 
else if (!strcasecmp(
var, 
"imapserver")) {
 
 1601        vmu->imapversion = imapversion;
 
 1602    } 
else if (!strcasecmp(
var, 
"imapport")) {
 
 1604        vmu->imapversion = imapversion;
 
 1605    } 
else if (!strcasecmp(
var, 
"imapflags")) {
 
 1607        vmu->imapversion = imapversion;
 
 1608    } 
else if (!strcasecmp(
var, 
"imappassword") || !strcasecmp(
var, 
"imapsecret")) {
 
 1610        vmu->imapversion = imapversion;
 
 1611    } 
else if (!strcasecmp(
var, 
"imapfolder")) {
 
 1613        vmu->imapversion = imapversion;
 
 1614    } 
else if (!strcasecmp(
var, 
"imapvmshareid")) {
 
 1616        vmu->imapversion = imapversion;
 
 1618    } 
else if (!strcasecmp(
var, 
"delete") || !strcasecmp(
var, 
"deletevoicemail")) {
 
 1620    } 
else if (!strcasecmp(
var, 
"saycid")){
 
 1622    } 
else if (!strcasecmp(
var, 
"sendvoicemail")){
 
 1624    } 
else if (!strcasecmp(
var, 
"review")){
 
 1626    } 
else if (!strcasecmp(
var, 
"leaveurgent")){
 
 1628    } 
else if (!strcasecmp(
var, 
"tempgreetwarn")){
 
 1630    } 
else if (!strcasecmp(
var, 
"messagewrap")){
 
 1632    } 
else if (!strcasecmp(
var, 
"operator")) {
 
 1634    } 
else if (!strcasecmp(
var, 
"envelope")){
 
 1636    } 
else if (!strcasecmp(
var, 
"moveheard")){
 
 1638    } 
else if (!strcasecmp(
var, 
"sayduration")){
 
 1640    } 
else if (!strcasecmp(
var, 
"saydurationm")){
 
 1641        if (sscanf(
value, 
"%30d", &x) == 1) {
 
 1646    } 
else if (!strcasecmp(
var, 
"forcename")){
 
 1648    } 
else if (!strcasecmp(
var, 
"forcegreetings")){
 
 1650    } 
else if (!strcasecmp(
var, 
"callback")) {
 
 1652    } 
else if (!strcasecmp(
var, 
"dialout")) {
 
 1654    } 
else if (!strcasecmp(
var, 
"exitcontext")) {
 
 1656    } 
else if (!strcasecmp(
var, 
"minsecs")) {
 
 1657        if (sscanf(
value, 
"%30d", &x) == 1 && x >= 0) {
 
 1663    } 
else if (!strcasecmp(
var, 
"maxsecs")) {
 
 1671    } 
else if (!strcasecmp(
var, 
"maxmsg")) {
 
 1681    } 
else if (!strcasecmp(
var, 
"nextaftercmd")) {
 
 1683    } 
else if (!strcasecmp(
var, 
"backupdeleted")) {
 
 1684        if (sscanf(
value, 
"%30d", &x) == 1)
 
 1698    } 
else if (!strcasecmp(
var, 
"volgain")) {
 
 1700    } 
else if (!strcasecmp(
var, 
"passwordlocation")) {
 
 1701        if (!strcasecmp(
value, 
"spooldir")) {
 
 1706    } 
else if (!strcasecmp(
var, 
"options")) {
 
 
 1713    int fds[2], pid = 0;
 
 1718        snprintf(
buf, 
len, 
"FAILURE: Pipe failed: %s", strerror(
errno));
 
 1727            snprintf(
buf, 
len, 
"FAILURE: Fork failed");
 
 1731            if (read(fds[0], 
buf, 
len) < 0) {
 
 1743            dup2(fds[1], STDOUT_FILENO);
 
 1749            execv(arg.v[0], arg.v);
 
 1750            printf(
"FAILURE: %s", strerror(
errno));
 
 
 1773        char cmd[255], 
buf[255];
 
 1775        ast_debug(1, 
"Verify password policies for %s\n", password);
 
 1780            if (!strncasecmp(
buf, 
"VALID", 5)) {
 
 1783            } 
else if (!strncasecmp(
buf, 
"FAILURE", 7)) {
 
 
 1808    if (!strcmp(vmu->
password, password)) {
 
 1813    if (strlen(password) > 10) {
 
 
 1833    while ((s = 
strsep(&stringp, 
"|"))) {
 
 
 1849        if (!strcasecmp(
var->name, 
"vmsecret")) {
 
 1851        } 
else if (!strcasecmp(
var->name, 
"secret") || !strcasecmp(
var->name, 
"password")) { 
 
 1855                        "\n\tmust be reset in voicemail.conf.\n", retval->
mailbox);
 
 1860        } 
else if (!strcasecmp(
var->name, 
"uniqueid")) {
 
 1862        } 
else if (!strcasecmp(
var->name, 
"pager")) {
 
 1864        } 
else if (!strcasecmp(
var->name, 
"email")) {
 
 1867        } 
else if (!strcasecmp(
var->name, 
"fullname")) {
 
 1869        } 
else if (!strcasecmp(
var->name, 
"context")) {
 
 1871        } 
else if (!strcasecmp(
var->name, 
"emailsubject")) {
 
 1874        } 
else if (!strcasecmp(
var->name, 
"emailbody")) {
 
 1878        } 
else if (!strcasecmp(
var->name, 
"imapuser")) {
 
 1880            retval->imapversion = imapversion;
 
 1881        } 
else if (!strcasecmp(
var->name, 
"imapserver")) {
 
 1883            retval->imapversion = imapversion;
 
 1884        } 
else if (!strcasecmp(
var->name, 
"imapport")) {
 
 1886            retval->imapversion = imapversion;
 
 1887        } 
else if (!strcasecmp(
var->name, 
"imapflags")) {
 
 1889            retval->imapversion = imapversion;
 
 1890        } 
else if (!strcasecmp(
var->name, 
"imappassword") || !strcasecmp(
var->name, 
"imapsecret")) {
 
 1892            retval->imapversion = imapversion;
 
 1893        } 
else if (!strcasecmp(
var->name, 
"imapfolder")) {
 
 1895            retval->imapversion = imapversion;
 
 1896        } 
else if (!strcasecmp(
var->name, 
"imapvmshareid")) {
 
 1898            retval->imapversion = imapversion;
 
 
 1917    for (i = 0; i < strlen(key); ++i) {
 
 
 1942    if ((retval = (ivm ? ivm : 
ast_calloc(1, 
sizeof(*retval))))) {
 
 1944            memset(retval, 0, 
sizeof(*retval));
 
 
 1989        if (cur->imapversion != imapversion) {
 
 2000        if ((vmu = (ivm ? ivm : 
ast_calloc(1, 
sizeof(*vmu))))) {
 
 2027            char *search_mailbox = 
NULL;
 
 2028            char *search_context = 
NULL;
 
 2032            vmu = 
find_user(ivm, search_mailbox, search_context);
 
 
 2069            "Context", 
S_OR(context, 
"default"),
 
 2071            "NewPassword", newpass);
 
 
 2097    char *category = 
NULL;
 
 2098    const char *tmp = 
NULL;
 
 2112            ast_verb(4, 
"Writing voicemail password to file %s succeeded\n", secretfn);
 
 2117            ast_log(
LOG_WARNING, 
"Writing voicemail password to file %s failed, falling back to config file\n", secretfn);
 
 2123                if (!strcasecmp(category, vmu->
context)) {
 
 2130                    value = strstr(tmp, 
",");
 
 2133                        sprintf(
new, 
"%s", newpassword);
 
 2136                        sprintf(
new, 
"%s%s", newpassword, 
value);
 
 2150                ast_test_suite_event_notify(
"PASSWORDCHANGED", 
"Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf");
 
 
 2190static int make_dir(
char *dest, 
int len, 
const char *context, 
const char *
ext, 
const char *folder)
 
 
 2207static int make_file(
char *dest, 
const int len, 
const char *dir, 
const int num)
 
 2209    return snprintf(dest, 
len, 
"%s/msg%04d", dir, num);
 
 
 2236    if (vmu && 
id == 0) {
 
 2237        return vmu->imapfolder;
 
 
 2295    int arraysize = (vmu->
maxmsg > count_msg ? vmu->
maxmsg : count_msg);
 
 2308    if (arraysize > 0) {
 
 
 2326static void vm_imap_delete(
char *file, 
int msgnum, 
struct ast_vm_user *vmu)
 
 2330    unsigned long messageNum;
 
 2333    if (msgnum < 0 && !imapgreetings) {
 
 2338    if (!(vms = get_vm_state_by_mailbox(vmu->
mailbox, vmu->
context, 1)) && !(vms = get_vm_state_by_mailbox(vmu->
mailbox, vmu->
context, 0))) {
 
 2339        ast_log(
LOG_WARNING, 
"Couldn't find a vm_state for mailbox %s. Unable to set \\DELETED flag for message %d\n", vmu->
mailbox, msgnum);
 
 2344        imap_delete_old_greeting(file, vms);
 
 2350    messageNum = vms->msgArray[msgnum];
 
 2351    if (messageNum == 0) {
 
 2352        ast_log(
LOG_WARNING, 
"msgnum %d, mailbox message %lu is zero.\n", msgnum, messageNum);
 
 2355    ast_debug(3, 
"deleting msgnum %d, which is mailbox message %lu\n", msgnum, messageNum);
 
 2357    snprintf (arg, 
sizeof(arg), 
"%lu", messageNum);
 
 2359    mail_setflag (vms->mailstream, arg, 
"\\DELETED");
 
 2360    mail_expunge(vms->mailstream);
 
 2364static void vm_imap_update_msg_id(
char *dir, 
int msgnum, 
const char *msg_id, 
struct ast_vm_user *vmu, 
struct ast_config *msg_cfg, 
int folder)
 
 2371    const char *duration_str;
 
 2415        sscanf(duration_str, 
"%30d", &duration);
 
 2431        vm_imap_delete(dir, msgnum, vmu);
 
 2437static int imap_retrieve_greeting(
const char *dir, 
const int msgnum, 
struct ast_vm_user *vmu)
 
 2440    char *
file, *filename;
 
 2450    if (msgnum > -1 || !imapgreetings) {
 
 2457            ast_debug(1, 
"Failed to procure file name from directory passed.\n");
 
 2463    if (!(vms_p = get_vm_state_by_mailbox(vmu->
mailbox, vmu->
context, 1)) &&
 
 2464        !(vms_p = get_vm_state_by_mailbox(vmu->
mailbox, vmu->
context, 0))) {
 
 2469        if (!(vms_p = create_vm_state_from_user(vmu))) {
 
 2476    *vms_p->introfn = 
'\0';
 
 2490    for (i = 0; i < vms_p->mailstream->nmsgs; i++) {
 
 2491        mail_fetchstructure(vms_p->mailstream, i + 1, &body);
 
 2493        if (body->nested.part && body->nested.part->next && body->nested.part->next->body.parameter->value) {
 
 2494            char *attachment = body->nested.part->next->body.parameter->value;
 
 2495            char copy[strlen(attachment) + 1];
 
 2497            strcpy(
copy, attachment); 
 
 2500            filename = 
strsep(&attachment, 
".");
 
 2501            if (!strcmp(filename, file)) {
 
 2503                vms_p->msgArray[vms_p->
curmsg] = i + 1;
 
 2505                save_body(body, vms_p, 
"2", attachment, 0);
 
 2516    if (curr_mbox != -1) {
 
 2518        if (init_mailstream(vms_p, curr_mbox) || !vms_p->mailstream) {
 
 2527static int imap_retrieve_file(
const char *dir, 
const int msgnum, 
const char *mailbox, 
const char *
context)
 
 2530    char *header_content;
 
 2531    char *attachedfilefmt;
 
 2535    FILE *text_file_ptr;
 
 2546        if (imapgreetings) {
 
 2547            res = imap_retrieve_greeting(dir, msgnum, vmu);
 
 2558    if (!(vms = get_vm_state_by_mailbox(vmu->
mailbox, vmu->
context, 1)) && !(vms = get_vm_state_by_mailbox(vmu->
mailbox, vmu->
context, 0))) {
 
 2573    if (curr_mbox < 0) {
 
 2574        ast_debug(3, 
"Mailbox folder curbox not set, defaulting to Inbox\n");
 
 2577    init_mailstream(vms, curr_mbox);
 
 2578    if (!vms->mailstream) {
 
 2585    snprintf(vms->introfn, 
sizeof(vms->introfn), 
"%sintro", vms->
fn);
 
 2593    ast_debug(3, 
"Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n", msgnum, vms->msgArray[msgnum]);
 
 2594    if (vms->msgArray[msgnum] == 0) {
 
 2602    header_content = mail_fetchheader (vms->mailstream, vms->msgArray[msgnum]);
 
 2606        ast_log(
LOG_ERROR, 
"Could not fetch header for message number %ld\n", vms->msgArray[msgnum]);
 
 2612    mail_fetchstructure(vms->mailstream, vms->msgArray[msgnum], &body);
 
 2616    if (body->nested.part && body->nested.part->next && body->nested.part->next->body.parameter->value) {
 
 2617        attachedfilefmt = 
ast_strdupa(body->nested.part->next->body.parameter->value);
 
 2626    strsep(&attachedfilefmt, 
".");
 
 2627    if (!attachedfilefmt) {
 
 2628        ast_log(
LOG_ERROR, 
"File format could not be obtained from IMAP message attachment\n");
 
 2633    save_body(body, vms, 
"2", attachedfilefmt, 0);
 
 2634    if (save_body(body, vms, 
"3", attachedfilefmt, 1)) {
 
 2635        *vms->introfn = 
'\0';
 
 2639    snprintf(text_file, 
sizeof(text_file), 
"%s.%s", vms->
fn, 
"txt");
 
 2641    if (!(text_file_ptr = fopen(text_file, 
"w"))) {
 
 2646    fprintf(text_file_ptr, 
"%s\n", 
"[message]");
 
 2648    if (get_header_by_tag(header_content, 
"X-Asterisk-VM-Caller-ID-Name:", 
buf, 
sizeof(
buf))) {
 
 2649        fprintf(text_file_ptr, 
"callerid=\"%s\" ", 
S_OR(
buf, 
""));
 
 2651    if (get_header_by_tag(header_content, 
"X-Asterisk-VM-Caller-ID-Num:", 
buf, 
sizeof(
buf))) {
 
 2652        fprintf(text_file_ptr, 
"<%s>\n", 
S_OR(
buf, 
""));
 
 2654    if (get_header_by_tag(header_content, 
"X-Asterisk-VM-Context:", 
buf, 
sizeof(
buf))) {
 
 2655        fprintf(text_file_ptr, 
"context=%s\n", 
S_OR(
buf, 
""));
 
 2657    if (get_header_by_tag(header_content, 
"X-Asterisk-VM-Orig-time:", 
buf, 
sizeof(
buf))) {
 
 2658        fprintf(text_file_ptr, 
"origtime=%s\n", 
S_OR(
buf, 
""));
 
 2660    if (get_header_by_tag(header_content, 
"X-Asterisk-VM-Duration:", 
buf, 
sizeof(
buf))) {
 
 2661        fprintf(text_file_ptr, 
"duration=%s\n", 
S_OR(
buf, 
""));
 
 2663    if (get_header_by_tag(header_content, 
"X-Asterisk-VM-Category:", 
buf, 
sizeof(
buf))) {
 
 2664        fprintf(text_file_ptr, 
"category=%s\n", 
S_OR(
buf, 
""));
 
 2666    if (get_header_by_tag(header_content, 
"X-Asterisk-VM-Flag:", 
buf, 
sizeof(
buf))) {
 
 2667        fprintf(text_file_ptr, 
"flag=%s\n", 
S_OR(
buf, 
""));
 
 2669    if (get_header_by_tag(header_content, 
"X-Asterisk-VM-Message-ID:", 
buf, 
sizeof(
buf))) {
 
 2670        fprintf(text_file_ptr, 
"msg_id=%s\n", 
S_OR(
buf, 
""));
 
 2672    fclose(text_file_ptr);
 
 2679static int folder_int(
const char *folder)
 
 2685    if (!strcasecmp(folder, imapfolder)) {
 
 2687    } 
else if (!strcasecmp(folder, 
"Old")) {
 
 2689    } 
else if (!strcasecmp(folder, 
"Work")) {
 
 2691    } 
else if (!strcasecmp(folder, 
"Family")) {
 
 2693    } 
else if (!strcasecmp(folder, 
"Friends")) {
 
 2695    } 
else if (!strcasecmp(folder, 
"Cust1")) {
 
 2697    } 
else if (!strcasecmp(folder, 
"Cust2")) {
 
 2699    } 
else if (!strcasecmp(folder, 
"Cust3")) {
 
 2701    } 
else if (!strcasecmp(folder, 
"Cust4")) {
 
 2703    } 
else if (!strcasecmp(folder, 
"Cust5")) {
 
 2705    } 
else if (!strcasecmp(folder, 
"Urgent")) {
 
 2712static int __messagecount(
const char *
context, 
const char *
mailbox, 
const char *folder)
 
 2720    int fold = folder_int(folder);
 
 2733    memset(&vmus, 0, 
sizeof(vmus));
 
 2741        if (vmu->imapuser[0] == 
'\0') {
 
 2749    if (vmu->imapuser[0] == 
'\0') {
 
 2756    vms_p = get_vm_state_by_imapuser(vmu->imapuser, 1);
 
 2758        vms_p = get_vm_state_by_mailbox(mailbox, 
context, 1);
 
 2761        ast_debug(3, 
"Returning before search - user is logged in\n");
 
 2773    vms_p = get_vm_state_by_imapuser(vmu->imapuser, 0);
 
 2775        vms_p = get_vm_state_by_mailbox(mailbox, 
context, 0);
 
 2779        vms_p = create_vm_state_from_user(vmu);
 
 2781    ret = init_mailstream(vms_p, fold);
 
 2782    if (!vms_p->mailstream) {
 
 2789        pgm = mail_newsearchpgm ();
 
 2790        hdr = mail_newsearchheader (
"X-Asterisk-VM-Extension", (
char *)(!
ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : 
mailbox));
 
 2791        hdr->next = mail_newsearchheader(
"X-Asterisk-VM-Context", (
char *) 
S_OR(
context, 
"default"));
 
 2817        vms_p->vmArrayIndex = 0;
 
 2818        mail_search_full (vms_p->mailstream, 
NULL, pgm, NIL);
 
 2819        if (fold == 0 && urgent == 0)
 
 2823        if (fold == 0 && urgent == 1)
 
 2826        mail_free_searchpgm(&pgm);
 
 2830        return vms_p->vmArrayIndex;
 
 2833        mail_ping(vms_p->mailstream);
 
 2843    check_quota(vms, vmu->imapfolder);
 
 2844    if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
 
 2845        ast_debug(1, 
"*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
 
 2855        ast_log(
LOG_WARNING, 
"Unable to leave message since we will exceed the maximum number of messages allowed (%u >= %u)\n", msgnum, vmu->
maxmsg);
 
 2874static int messagecount(
const char *mailbox_id, 
const char *folder)
 
 2886        count = __messagecount(
context, mailbox, 
"INBOX") + __messagecount(
context, mailbox, 
"Urgent");
 
 2888        count = __messagecount(
context, mailbox, folder);
 
 2890    return count < 0 ? 0 : count;
 
 2893static int imap_store_file(
const char *dir, 
const char *mailboxuser, 
const char *mailboxcontext, 
int msgnum, 
struct ast_channel *chan, 
struct ast_vm_user *vmu, 
char *fmt, 
int duration, 
struct vm_state *vms, 
const char *
flag, 
const char *msg_id)
 
 2901    char tmp[80] = 
"/tmp/astmail-XXXXXX";
 
 2907    char *imap_flags = NIL;
 
 2911    snprintf(mailbox, 
sizeof(mailbox), 
"%s@%s", vmu->
mailbox, vmu->
context);
 
 2916        if(!imapgreetings) {
 
 2923    if (imap_check_limits(chan, vms, vmu, msgcount)) {
 
 2929        ast_debug(3, 
"Setting message flag \\\\FLAGGED.\n");
 
 2930        imap_flags = 
"\\FLAGGED";
 
 2946    snprintf(introfn, 
sizeof(introfn), 
"%sintro", 
fn);
 
 2961    if (!strcmp(fmt, 
"wav49"))
 
 2963    ast_debug(3, 
"Storing file '%s', format '%s'\n", 
fn, fmt);
 
 2976    if (msgnum < 0 && imapgreetings) {
 
 2981        imap_delete_old_greeting(
fn, vms);
 
 2987        fn, introfn, fmt, duration, 1, chan, 
NULL, 1, 
flag, msg_id);
 
 2995            *(vmu->
email) = 
'\0';
 
 3004    ((
char *) 
buf)[
len] = 
'\0';
 
 3006    ret = init_mailstream(vms, box);
 
 3008        imap_mailbox_name(mailbox, 
sizeof(mailbox), vms, box, 1);
 
 3010        if(!mail_append_full(vms->mailstream, mailbox, imap_flags, NIL, &
str))
 
 3026        *(vmu->
email) = 
'\0';
 
 3045static int inboxcount2(
const char *mailbox_context, 
int *urgentmsgs, 
int *newmsgs, 
int *oldmsgs)
 
 3060    ast_debug(3, 
"Mailbox is set to %s\n", mailbox_context);
 
 3067    if (strchr(mailbox_context, 
',')) {
 
 3068        int tmpnew, tmpold, tmpurgent;
 
 3071        while ((cur = 
strsep(&mb, 
", "))) {
 
 3081                        *urgentmsgs += tmpurgent;
 
 3093        mailboxnc = (
char *) mailbox_context;
 
 3102        if ((count = __messagecount(
context, mailboxnc, vmu->imapfolder)) < 0) {
 
 3110        if ((count = __messagecount(
context, mailboxnc, 
"Old")) < 0) {
 
 3116        if ((count = __messagecount(
context, mailboxnc, 
"Urgent")) < 0) {
 
 3119        *urgentmsgs = count;
 
 3136    char tmp[256], *tmp2, *box, *
context;
 
 3139    if (strchr(tmp2, 
',') || strchr(tmp2, 
'&')) {
 
 3140        while ((box = 
strsep(&tmp2, 
",&"))) {
 
 3148    if ((
context = strchr(tmp, 
'@'))) {
 
 3153    return __messagecount(
context, tmp, folder) > 0 ? 1 : 0;
 
 3175    char messagestring[10]; 
 
 3176    if (msgnum >= recip->
maxmsg) {
 
 3180    if (!(sendvms = get_vm_state_by_imapuser(vmu->imapuser, 0))) {
 
 3184    if (!get_vm_state_by_imapuser(recip->imapuser, 0)) {
 
 3188    snprintf(messagestring, 
sizeof(messagestring), 
"%ld", sendvms->msgArray[msgnum]);
 
 3190    if ((mail_copy(sendvms->mailstream, messagestring, (
char *) 
mbox(vmu, imbox)) == T)) {
 
 3199static void imap_mailbox_name(
char *spec, 
size_t len, 
struct vm_state *vms, 
int box, 
int use_folder)
 
 3201    char tmp[256], *t = tmp;
 
 3202    size_t left = 
sizeof(tmp);
 
 3235        snprintf(spec, 
len, 
"%s%s", tmp, use_folder? vms->imapfolder: 
"INBOX");
 
 3237        snprintf(spec, 
len, 
"%s%s", tmp, greetingfolder);
 
 3241            snprintf(spec, 
len, 
"%s%s%c%s", tmp, imapparentfolder, delimiter, 
mbox(
NULL, box));
 
 3243            snprintf(spec, 
len, 
"%s%s", tmp, 
mbox(
NULL, box));
 
 3248static int init_mailstream(
struct vm_state *vms, 
int box)
 
 3250    MAILSTREAM *stream = NIL;
 
 3258    ast_debug(3, 
"vm_state user is:%s\n", vms->imapuser);
 
 3259    if (vms->mailstream == NIL || !vms->mailstream) {
 
 3262        stream = vms->mailstream;
 
 3267    if (delimiter == 
'\0') {        
 
 3269#ifdef USE_SYSTEM_IMAP 
 3270#include <imap/linkage.c> 
 3271#elif defined(USE_SYSTEM_CCLIENT) 
 3272#include <c-client/linkage.c> 
 3277        imap_mailbox_name(tmp, 
sizeof(tmp), vms, 0, 1);
 
 3280        stream = mail_open (stream, tmp, 
debug ? OP_DEBUG : NIL);
 
 3283        if (stream == NIL) {
 
 3287        get_mailbox_delimiter(vms, stream);
 
 3289        for (cp = vms->imapfolder; *cp; cp++)
 
 3294    imap_mailbox_name(tmp, 
sizeof(tmp), vms, box, 1);
 
 3295    ast_debug(3, 
"Before mail_open, server: %s, box:%d\n", tmp, box);
 
 3298    vms->mailstream = mail_open (stream, tmp, 
debug ? OP_DEBUG : NIL);
 
 3300    if (vms->mailstream && !mail_status(vms->mailstream, tmp, SA_UIDNEXT)) {
 
 3301        mail_create(vms->mailstream, tmp);
 
 3305    if (vms->mailstream == NIL) {
 
 3325    ast_copy_string(vms->imapfolder, vmu->imapfolder, 
sizeof(vms->imapfolder));
 
 3326    ast_copy_string(vms->imapserver, vmu->imapserver, 
sizeof(vms->imapserver));
 
 3328    ast_copy_string(vms->imapflags, vmu->imapflags, 
sizeof(vms->imapflags));
 
 3329    vms->imapversion = vmu->imapversion;
 
 3330    ast_debug(3, 
"Before init_mailstream, user is %s\n", vmu->imapuser);
 
 3332    if (init_mailstream(vms, box) || !vms->mailstream) {
 
 3341        ast_debug(3, 
"Mailbox name set to: %s, about to check quotas\n", 
mbox(vmu, box));
 
 3342        check_quota(vms, (
char *) 
mbox(vmu, box));
 
 3346    pgm = mail_newsearchpgm();
 
 3349    hdr = mail_newsearchheader(
"X-Asterisk-VM-Extension", (!
ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : vmu->
mailbox));
 
 3350    hdr->next = mail_newsearchheader(
"X-Asterisk-VM-Context", vmu->
context);
 
 3361    } 
else if (box == 
NEW_FOLDER && urgent == 0) {
 
 3371    ast_debug(3, 
"Before mail_search_full, user is %s\n", vmu->imapuser);
 
 3373    vms->vmArrayIndex = 0;
 
 3374    mail_search_full (vms->mailstream, 
NULL, pgm, NIL);
 
 3375    vms->
lastmsg = vms->vmArrayIndex - 1;
 
 3376    mail_free_searchpgm(&pgm);
 
 3382        ast_log(
LOG_WARNING, 
"The code expects the old messages to be checked first, fix the code.\n");
 
 3393static void write_file(
char *filename, 
char *buffer, 
unsigned long len)
 
 3397    if (!filename || !buffer) {
 
 3401    if (!(output = fopen(filename, 
"w"))) {
 
 3406    if (fwrite(buffer, 
len, 1, output) != 1) {
 
 3407        if (ferror(output)) {
 
 3414static void update_messages_by_imapuser(
const char *
user, 
unsigned long number)
 
 3416    struct vm_state *vms = get_vm_state_by_imapuser(
user, 1);
 
 3418    if (!vms && !(vms = get_vm_state_by_imapuser(
user, 0))) {
 
 3422    ast_debug(3, 
"saving mailbox message number %lu as message %d. Interactive set to %d\n", 
number, vms->vmArrayIndex, vms->interactive);
 
 3425    if (vms->vmArrayIndex >= vms->msg_array_max) {
 
 3426        long *new_mem = 
ast_realloc(vms->msgArray, 2 * vms->msg_array_max * 
sizeof(
long));
 
 3430        vms->msgArray = new_mem;
 
 3431        vms->msg_array_max *= 2;
 
 3434    vms->msgArray[vms->vmArrayIndex++] = 
number;
 
 3437void mm_searched(MAILSTREAM *stream, 
unsigned long number)
 
 3441    if (!(
user = get_user_by_mailbox(mailbox, 
buf, 
sizeof(
buf))))
 
 3447static struct ast_vm_user *find_user_realtime_imapuser(
const char *imapuser)
 
 3472void mm_exists(MAILSTREAM * stream, 
unsigned long number)
 
 3481void mm_expunged(MAILSTREAM * stream, 
unsigned long number)
 
 3490void mm_flags(MAILSTREAM * stream, 
unsigned long number)
 
 3499void mm_notify(MAILSTREAM * stream, 
char *
string, 
long errflg)
 
 3501    ast_debug(5, 
"Entering NOTIFY callback, errflag is %ld, string is %s\n", errflg, 
string);
 
 3502    mm_log (
string, errflg);
 
 3506void mm_list(MAILSTREAM * stream, 
int delim, 
char *
mailbox, 
long attributes)
 
 3508    if (delimiter == 
'\0') {
 
 3513    if (attributes & LATT_NOINFERIORS)
 
 3515    if (attributes & LATT_NOSELECT)
 
 3517    if (attributes & LATT_MARKED)
 
 3519    if (attributes & LATT_UNMARKED)
 
 3524void mm_lsub(MAILSTREAM * stream, 
int delim, 
char *
mailbox, 
long attributes)
 
 3527    if (attributes & LATT_NOINFERIORS)
 
 3529    if (attributes & LATT_NOSELECT)
 
 3531    if (attributes & LATT_MARKED)
 
 3533    if (attributes & LATT_UNMARKED)
 
 3538void mm_status(MAILSTREAM * stream, 
char *
mailbox, MAILSTATUS * 
status)
 
 3547    if (
status->flags & SA_MESSAGES) {
 
 3550    if (
status->flags & SA_RECENT) {
 
 3553    if (
status->flags & SA_UNSEEN) {
 
 3556    if (
status->flags & SA_UIDVALIDITY) {
 
 3559    if (
status->flags & SA_UIDNEXT) {
 
 3568void mm_log(
char *
string, 
long errflg)
 
 3570    switch ((
short) errflg) {
 
 3572            ast_debug(1, 
"IMAP Info: %s\n", 
string);
 
 3585void mm_dlog(
char *
string)
 
 3591void mm_login(NETMBX * mb, 
char *
user, 
char *pwd, 
long trial)
 
 3595    ast_debug(4, 
"Entering callback mm_login\n");
 
 3604            if (!strcasecmp(mb->user, vmu->imapuser)) {
 
 3610            if ((vmu = find_user_realtime_imapuser(mb->user))) {
 
 3619void mm_critical(MAILSTREAM * stream)
 
 3624void mm_nocritical(MAILSTREAM * stream)
 
 3629long mm_diskerror(MAILSTREAM * stream, 
long errcode, 
long serious)
 
 3631    kill (getpid (), SIGSTOP);
 
 3636void mm_fatal(
char *
string)
 
 3642static void mm_parsequota(MAILSTREAM *stream, 
unsigned char *msg, QUOTALIST *pquota)
 
 3646    char buf[1024] = 
"";
 
 3647    unsigned long usage = 0, limit = 0;
 
 3650        usage = pquota->usage;
 
 3651        limit = pquota->limit;
 
 3652        pquota = pquota->next;
 
 3655    if (!(
user = get_user_by_mailbox(mailbox, 
buf, 
sizeof(
buf))) || (!(vms = get_vm_state_by_imapuser(
user, 2)) && !(vms = get_vm_state_by_imapuser(
user, 0)))) {
 
 3662    vms->quota_usage = 
usage;
 
 3663    vms->quota_limit = limit;
 
 3666static char *get_header_by_tag(
char *
header, 
char *tag, 
char *
buf, 
size_t len)
 
 3668    char *start, *eol_pnt;
 
 3674    taglen = strlen(tag) + 1;
 
 3685    if ((eol_pnt = strchr(
buf,
'\r')) || (eol_pnt = strchr(
buf,
'\n')))
 
 3690static char *get_user_by_mailbox(
char *mailbox, 
char *
buf, 
size_t len)
 
 3692    char *start, *eol_pnt, *
quote;
 
 3697    if (!(start = strstr(mailbox, 
"/user=")))
 
 3703        if ((eol_pnt = strchr(
buf, 
'/')) || (eol_pnt = strchr(
buf, 
'}'))) {
 
 3708        if ((eol_pnt = strchr(
quote + 1, 
'"'))) {
 
 3719    pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
 
 3720    if ((vms_p = pthread_getspecific(ts_vmstate.key)) && !strcmp(vms_p->imapuser, vmu->imapuser) && !strcmp(vms_p->
username, vmu->
mailbox)) {
 
 3723    ast_debug(5, 
"Adding new vmstate for %s\n", vmu->imapuser);
 
 3725    if (!(vms_p = 
ast_calloc(1, 
sizeof(*vms_p))))
 
 3727    ast_copy_string(vms_p->imapuser, vmu->imapuser, 
sizeof(vms_p->imapuser));
 
 3728    ast_copy_string(vms_p->imapfolder, vmu->imapfolder, 
sizeof(vms_p->imapfolder));
 
 3729    ast_copy_string(vms_p->imapserver, vmu->imapserver, 
sizeof(vms_p->imapserver));
 
 3730    ast_copy_string(vms_p->imapport, vmu->imapport, 
sizeof(vms_p->imapport));
 
 3731    ast_copy_string(vms_p->imapflags, vmu->imapflags, 
sizeof(vms_p->imapflags));
 
 3734    vms_p->mailstream = NIL; 
 
 3735    vms_p->imapversion = vmu->imapversion;
 
 3736    ast_debug(5, 
"Copied %s to %s\n", vmu->imapuser, vms_p->imapuser);
 
 3740    init_vm_state(vms_p);
 
 3741    vmstate_insert(vms_p);
 
 3745static struct vm_state *get_vm_state_by_imapuser(
const char *
user, 
int interactive)
 
 3747    struct vmstate *vlist = 
NULL;
 
 3751        pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
 
 3752        if ((vms = pthread_getspecific(ts_vmstate.key)) && !strcmp(vms->imapuser, 
user)) {
 
 3763        if (vlist->vms->imapversion != imapversion) {
 
 3767        if (!strcmp(vlist->vms->imapuser, 
user) && (interactive == 2 || vlist->vms->interactive == interactive)) {
 
 3779static struct vm_state *get_vm_state_by_mailbox(
const char *mailbox, 
const char *
context, 
int interactive)
 
 3782    struct vmstate *vlist = 
NULL;
 
 3783    const char *local_context = 
S_OR(context, 
"default");
 
 3787        pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
 
 3788        if ((vms = pthread_getspecific(ts_vmstate.key)) &&
 
 3789            !strcmp(vms->
username,mailbox) && !strcmp(vms->
context, local_context)) {
 
 3797            ast_debug(3, 
"error: vms is NULL for %s\n", mailbox);
 
 3800        if (vlist->vms->imapversion != imapversion) {
 
 3804        ast_debug(3, 
"comparing mailbox %s@%s (i=%d) to vmstate mailbox %s@%s (i=%d)\n", mailbox, local_context, interactive, vlist->vms->username, vlist->vms->context, vlist->vms->interactive);
 
 3806        if (!strcmp(vlist->vms->username, mailbox) && !strcmp(vlist->vms->context, local_context) && vlist->vms->interactive == interactive) {
 
 3814    ast_debug(3, 
"%s not found in vmstates\n", mailbox);
 
 3819static void vmstate_insert(
struct vm_state *vms)
 
 3827    if (vms->interactive == 1) {
 
 3833            vms->vmArrayIndex = altvms->vmArrayIndex;
 
 3838            vms->persist_vms = altvms;
 
 3840#ifdef REALLY_FAST_EVEN_IF_IT_MEANS_RESOURCE_LEAKS 
 3841            vms->mailstream = altvms->mailstream;
 
 3843            vms->mailstream = NIL;
 
 3854    ast_debug(3, 
"Inserting vm_state for user:%s, mailbox %s\n", vms->imapuser, vms->
username);
 
 3861static void vmstate_delete(
struct vm_state *vms)
 
 3863    struct vmstate *vc = 
NULL;
 
 3868    if (vms->interactive == 1 && (altvms = vms->persist_vms)) {
 
 3872        altvms->updated = 1;
 
 3873        vms->mailstream = mail_close(vms->mailstream);
 
 3879    ast_debug(3, 
"Removing vm_state for user:%s, mailbox %s\n", vms->imapuser, vms->
username);
 
 3883        if (vc->vms == vms) {
 
 3894        vc->vms->msgArray = 
NULL;
 
 3895        vc->vms->msg_array_max = 0;
 
 3903static void set_update(MAILSTREAM * stream)
 
 3907    char buf[1024] = 
"";
 
 3909    if (!(
user = get_user_by_mailbox(mailbox, 
buf, 
sizeof(
buf))) || !(vms = get_vm_state_by_imapuser(
user, 0))) {
 
 3920static void init_vm_state(
struct vm_state *vms)
 
 3923    vms->msgArray = 
ast_calloc(vms->msg_array_max, 
sizeof(
long));
 
 3924    if (!vms->msgArray) {
 
 3926        vms->msg_array_max = 0;
 
 3928    vms->vmArrayIndex = 0;
 
 3932static int save_body(BODY *body, 
struct vm_state *vms, 
char *section, 
char *format, 
int is_intro)
 
 3936    char *
fn = is_intro ? vms->introfn : vms->
fn;
 
 3937    unsigned long len = 0;
 
 3938    unsigned long newlen = 0;
 
 3941    if (!body || body == NIL)
 
 3945    body_content = mail_fetchbody(vms->mailstream, vms->msgArray[vms->
curmsg], section, &
len);
 
 3949            "Msgno %ld, section %s. The body's content size %ld is huge (max %ld). User:%s, mailbox %s\n",
 
 3953    if (body_content != NIL && 
len) {
 
 3954        snprintf(filename, 
sizeof(filename), 
"%s.%s", 
fn, format);
 
 3956        body_decoded = rfc822_base64((
unsigned char *) body_content, 
len, &newlen);
 
 3958        if (!newlen || !body_decoded) {
 
 3961        write_file(filename, (
char *) body_decoded, newlen);
 
 3963        ast_debug(5, 
"Body of message is NULL.\n");
 
 3977static void get_mailbox_delimiter(
struct vm_state *vms, MAILSTREAM *stream) {
 
 3979    snprintf(tmp, 
sizeof(tmp), 
"{%s}", 
S_OR(vms->imapserver, imapserver));
 
 3980    mail_list(stream, tmp, 
"*");
 
 3990static void check_quota(
struct vm_state *vms, 
char *mailbox) {
 
 3992    mail_parameters(
NULL, SET_QUOTA, (
void *) mm_parsequota);
 
 3993    ast_debug(3, 
"Mailbox name set to: %s, about to check quotas\n", mailbox);
 
 3994    if (vms && vms->mailstream != 
NULL) {
 
 3995        imap_getquotaroot(vms->mailstream, mailbox);
 
 4018#define MSG_ID_LEN 256 
 4041#define MAKE_SQL_PTRA(__sql_fmt) \ 
 4044    char *__sql = ast_alloca(strlen(__sql_fmt) + odbc_table_len); \ 
 4045    sprintf(__sql, __sql_fmt, odbc_table);  \ 
 4059#define MAKE_SQL_PTRA2(__sql_fmt) \ 
 4062    char *__sql = ast_alloca(strlen(__sql_fmt) + (odbc_table_len * 2)); \ 
 4063    sprintf(__sql, __sql_fmt, odbc_table, odbc_table);  \ 
 4067struct generic_prepare_struct {
 
 4075    struct generic_prepare_struct *gps = data;
 
 4079    res = SQLAllocHandle(SQL_HANDLE_STMT, obj->
con, &stmt);
 
 4080    if (!SQL_SUCCEEDED(res)) {
 
 4085    if (!SQL_SUCCEEDED(res)) {
 
 4087        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4090    for (i = 0; i < gps->argc; i++)
 
 4091        SQLBindParameter(stmt, i + 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(gps->argv[i]), 0, gps->argv[i], 0, 
NULL);
 
 4096static void odbc_update_msg_id(
char *dir, 
int msg_num, 
char *msg_id)
 
 4099    char *sql = MAKE_SQL_PTRA(
"UPDATE %s SET msg_id=? WHERE dir=? AND msgnum=?");
 
 4101    char msg_num_str[20];
 
 4102    char *argv[] = { msg_id, dir, msg_num_str };
 
 4103    struct generic_prepare_struct gps = { .sql = sql, .argc = 3, .argv = argv };
 
 4104    SCOPE_ENTER(3, 
"dir: %s msg_num: %d msg_id: %s\n", dir, msg_num, msg_id);
 
 4111    snprintf(msg_num_str, 
sizeof(msg_num_str), 
"%d", msg_num);
 
 4116        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4122#define AUDIO_ON_DISK_MAGIC "AUDMAGIC" 
 4123#define AUDIO_ON_DISK_MAGIC_LEN 8 
 4125static void odbc_update_set_audmagic(
char *dir, 
int msg_num)
 
 4128    char *sql = MAKE_SQL_PTRA(
"UPDATE %s SET recording=? WHERE dir=? AND msgnum=?");
 
 4130    SQLLEN datalen = AUDIO_ON_DISK_MAGIC_LEN;
 
 4131    SQLLEN indlen = datalen;
 
 4133    char msg_num_str[20];
 
 4134    SCOPE_ENTER(3, 
"dir: %s msg_num: %d\n", dir, msg_num);
 
 4141    res = SQLAllocHandle(SQL_HANDLE_STMT, obj->
con, &stmt);
 
 4142    if (!SQL_SUCCEEDED(res)) {
 
 4147    snprintf(msg_num_str, 
sizeof(msg_num_str), 
"%d", msg_num);
 
 4149    SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY,
 
 4150        datalen, 0, (
void *) AUDIO_ON_DISK_MAGIC,
 
 4153    SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
 
 4154        strlen(dir), 0, (
void *) dir, 0, 
NULL);
 
 4156    SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
 
 4157        strlen(msg_num_str), 0, (
void *) msg_num_str, 0, 
NULL);
 
 4160    if (!SQL_SUCCEEDED(res)) {
 
 4164    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4171static int odbc_store_message(
const char *dir, 
const char *mailboxuser, 
const char *mailboxcontext, 
int msgnum);
 
 4187static int odbc_retrieve_message(
char *dir, 
int msgnum)
 
 4193    void *fdm = MAP_FAILED;
 
 4194    SQLSMALLINT colcount = 0;
 
 4196    char *sql = MAKE_SQL_PTRA(
"SELECT * FROM %s WHERE dir=? AND msgnum=?");
 
 4201    SQLSMALLINT datatype;
 
 4202    SQLSMALLINT decimaldigits;
 
 4203    SQLSMALLINT nullable;
 
 4208    char *fn = MAKE_FILE_PTRA(dir, msgnum);
 
 4209    char *full_fn = MAKE_FILE_EXT_PTRA(dir, msgnum, 
"txt");
 
 4211    char *mailboxuser = 
NULL;
 
 4212    char *mailboxcontext = 
NULL;
 
 4214    char *argv[] = { dir, msgnums };
 
 4215    struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };
 
 4217    int storage_conversion_to_disk = 0;
 
 4218    int storage_conversion_to_odbc = 0;
 
 4219    SCOPE_ENTER(3, 
"dir: %s msgnum: %d  msgtype: %s\n", dir, msgnum, msgnum < 0 ? 
"Greeting" : 
"Message");
 
 4227    c = strchr(fmt, 
'|');
 
 4230    if (!strcasecmp(fmt, 
"wav49"))
 
 4233    snprintf(msgnums, 
sizeof(msgnums), 
"%d", msgnum);
 
 4235    ast_trace(-1, 
"Opening '%s' for writing\n", full_fn);
 
 4236    if (!(f = fopen(full_fn, 
"w+"))) {
 
 4241    sprintf(full_fn, 
"%s.%s", fn, fmt); 
 
 4249    res = SQLFetch(stmt);
 
 4250    if (!SQL_SUCCEEDED(res)) {
 
 4251        if (res != SQL_NO_DATA) {
 
 4254        goto bail_with_handle;
 
 4257    res = SQLNumResultCols(stmt, &colcount);
 
 4258    if (!SQL_SUCCEEDED(res)) {
 
 4260        goto bail_with_handle;
 
 4263    fprintf(f, 
"[message]\n");
 
 4264    for (x = 0; x < colcount; x++) {
 
 4267        collen = 
sizeof(coltitle);
 
 4268        res = SQLDescribeCol(stmt, x + 1, (
unsigned char *) coltitle, 
sizeof(coltitle), &collen,
 
 4269                            &datatype, &colsize, &decimaldigits, &nullable);
 
 4270        if (!SQL_SUCCEEDED(res)) {
 
 4272            goto bail_with_handle;
 
 4275        if (!strcasecmp(coltitle, 
"recording")) {
 
 4279            res = SQLGetData(stmt, x + 1, SQL_BINARY, rowdata, 0, &colsize2);
 
 4281            ast_trace(-1, 
"Audio size: %ld\n", colsize2);
 
 4282            if (colsize2 == AUDIO_ON_DISK_MAGIC_LEN) {
 
 4283                res = SQLGetData(stmt, x + 1, SQL_BINARY, rowdata, AUDIO_ON_DISK_MAGIC_LEN, 
NULL);
 
 4284                if (memcmp(rowdata, AUDIO_ON_DISK_MAGIC, AUDIO_ON_DISK_MAGIC_LEN) != 0) {
 
 4286                        rowdata[0], rowdata[1], rowdata[2], rowdata[3], rowdata[4], rowdata[5], rowdata[6],
 
 4287                        rowdata[7], full_fn);
 
 4288                    goto bail_with_handle;
 
 4290                ast_trace(-1, 
"Audio is stored on disk.  No need to write '%s'\n", full_fn);
 
 4292                    storage_conversion_to_odbc = 1;
 
 4298            ast_trace(-1, 
"Opening '%s' for writing\n", full_fn);
 
 4302                goto bail_with_handle;
 
 4305                storage_conversion_to_disk = 1;
 
 4308            lseek(fd, fdlen - 1, SEEK_SET);
 
 4309            if (write(fd, tmp, 1) != 1) {
 
 4315            for (offset = 0; offset < colsize2; offset += 
CHUNKSIZE) {
 
 4316                if ((fdm = mmap(
NULL, 
CHUNKSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)) == MAP_FAILED) {
 
 4318                    goto bail_with_handle;
 
 4320                res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, 
CHUNKSIZE, 
NULL);
 
 4322                if (!SQL_SUCCEEDED(res)) {
 
 4325                    goto bail_with_handle;
 
 4328            if (truncate(full_fn, fdlen) < 0) {
 
 4331            ast_trace(-1, 
"Wrote %d bytes to '%s'\n", (
int)fdlen, full_fn);
 
 4333            res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, 
sizeof(rowdata), 
NULL);
 
 4334            if (res == SQL_NULL_DATA && !strcasecmp(coltitle, 
"msg_id")) {
 
 4340                ast_trace(-1, 
"msg_id was NULL.  Generating new one: %s\n", msg_id);
 
 4341                snprintf(rowdata, 
sizeof(rowdata), 
"%s", msg_id);
 
 4342            } 
else if (!strcasecmp(coltitle, 
"mailboxuser")) {
 
 4344            } 
else if (!strcasecmp(coltitle, 
"mailboxcontext")) {
 
 4346            } 
else if (res == SQL_NULL_DATA && !strcasecmp(coltitle, 
"category")) {
 
 4348                ast_trace(-1, 
"Ignoring null category column in ODBC voicemail retrieve_file.\n");
 
 4350            } 
else if (!SQL_SUCCEEDED(res)) {
 
 4352                goto bail_with_handle;
 
 4354            if (strcasecmp(coltitle, 
"msgnum") && strcasecmp(coltitle, 
"dir")) {
 
 4355                fprintf(f, 
"%s=%s\n", coltitle, rowdata);
 
 4361    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4375        odbc_update_msg_id(dir, msgnum, msg_id);
 
 4378    if (SQL_SUCCEEDED(res)) {
 
 4379        if (storage_conversion_to_disk) {
 
 4385            SCOPE_CALL(-1, odbc_update_set_audmagic, dir, msgnum);
 
 4387        if (storage_conversion_to_odbc) {
 
 4394            SCOPE_CALL(-1, odbc_store_message, dir, mailboxuser, mailboxcontext, msgnum);
 
 4410static int odbc_last_message_index(
char *dir)
 
 4415    char *sql = MAKE_SQL_PTRA(
"SELECT msgnum FROM %s WHERE dir=? order by msgnum desc");
 
 4417    char *argv[] = { dir };
 
 4418    struct generic_prepare_struct gps = { .sql = sql, .argc = 1, .argv = argv };
 
 4433    res = SQLFetch(stmt);
 
 4434    if (!SQL_SUCCEEDED(res)) {
 
 4435        if (res == SQL_NO_DATA) {
 
 4436            ast_trace(-1, 
"Directory '%s' has no messages and therefore no index was retrieved.\n", dir);
 
 4440        goto bail_with_handle;
 
 4443    res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, 
sizeof(rowdata), 
NULL);
 
 4444    if (!SQL_SUCCEEDED(res)) {
 
 4446        goto bail_with_handle;
 
 4449    if (sscanf(rowdata, 
"%30d", &x) != 1) {
 
 4454    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4471static int odbc_message_exists(
char *dir, 
int msgnum)
 
 4476    char *sql = MAKE_SQL_PTRA(
"SELECT COUNT(*) FROM %s WHERE dir=? AND msgnum=?");
 
 4479    char *argv[] = { dir, msgnums };
 
 4480    struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };
 
 4482    SCOPE_ENTER(3, 
"dir: %s msgnum: %d\n", dir, msgnum);
 
 4489    snprintf(msgnums, 
sizeof(msgnums), 
"%d", msgnum);
 
 4496    res = SQLFetch(stmt);
 
 4497    if (!SQL_SUCCEEDED(res)) {
 
 4499        goto bail_with_handle;
 
 4502    res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, 
sizeof(rowdata), 
NULL);
 
 4503    if (!SQL_SUCCEEDED(res)) {
 
 4505        goto bail_with_handle;
 
 4508    if (sscanf(rowdata, 
"%30d", &x) != 1) {
 
 4513    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4529static int odbc_count_messages(
struct ast_vm_user *vmu, 
char *dir)
 
 4534    char *sql = MAKE_SQL_PTRA(
"SELECT COUNT(*) FROM %s WHERE dir=?");
 
 4536    char *argv[] = { dir };
 
 4537    struct generic_prepare_struct gps = { .sql = sql, .argc = 1, .argv = argv };
 
 4552    res = SQLFetch(stmt);
 
 4553    if (!SQL_SUCCEEDED(res)) {
 
 4555        goto bail_with_handle;
 
 4558    res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, 
sizeof(rowdata), 
NULL);
 
 4559    if (!SQL_SUCCEEDED(res)) {
 
 4561        goto bail_with_handle;
 
 4564    if (sscanf(rowdata, 
"%30d", &x) != 1) {
 
 4569    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4584#define DELETE_SQL_FMT "DELETE FROM %s WHERE dir=? AND msgnum=?" 
 4585static void odbc_delete_message(
const char *sdir, 
int smsg)
 
 4588    char *sql = MAKE_SQL_PTRA(DELETE_SQL_FMT);
 
 4590    char *argv[] = { 
NULL, msgnums };
 
 4591    struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };
 
 4593    SCOPE_ENTER(3, 
"sdir: %s smsg: %d\n", sdir, smsg);
 
 4602    snprintf(msgnums, 
sizeof(msgnums), 
"%d", smsg);
 
 4607        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4612        char *src_fn = MAKE_FILE_PTRA(sdir, smsg);
 
 4613        ast_trace(-1, 
"Audio stored on disk. Deleting '%s'\n", src_fn);
 
 4631#define COPY_SQL_FMT "INSERT INTO %s (dir, msgnum, msg_id, context, callerid, origtime, " \ 
 4632    "duration, recording, flag, mailboxuser, mailboxcontext) " \ 
 4633    "SELECT ?,?,msg_id,context,callerid,origtime,duration,recording,flag,?,? " \ 
 4634        "FROM %s WHERE dir=? AND msgnum=?" 
 4635static void odbc_copy_message(
char *sdir, 
int smsg, 
char *ddir, 
int dmsg, 
char *dmailboxuser, 
char *dmailboxcontext)
 
 4638    char *sql = MAKE_SQL_PTRA2(COPY_SQL_FMT);
 
 4642    char *argv[] = { ddir, msgnumd, dmailboxuser, dmailboxcontext, sdir, msgnums };
 
 4643    struct generic_prepare_struct gps = { .sql = sql, .argc = 6, .argv = argv };
 
 4644    SCOPE_ENTER(3, 
"sdir: %s smsg: %d duser: %s dcontext: %s ddir: %s dmsg: %d\n",
 
 4645        sdir, smsg, dmailboxuser, dmailboxcontext, ddir, dmsg);
 
 4647    SCOPE_CALL(-1, odbc_delete_message, ddir, dmsg);
 
 4654    snprintf(msgnums, 
sizeof(msgnums), 
"%d", smsg);
 
 4655    snprintf(msgnumd, 
sizeof(msgnumd), 
"%d", dmsg);
 
 4659        ast_log(
AST_LOG_WARNING, 
"SQL Execute error!\n[%s] (You probably don't have MySQL 4.1 or later installed)\n\n", sql);
 
 4661        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4665        char *src_fn = MAKE_FILE_PTRA(sdir, smsg);
 
 4666        char *dst_fn = MAKE_FILE_PTRA(ddir, dmsg);
 
 4668        ast_trace(-1, 
"Audio stored on disk.  Copying '%s' to '%s'\n", src_fn, dst_fn);
 
 4678    const char *msgnums;
 
 4683    const char *callerid;
 
 4684    const char *origtime;
 
 4685    const char *duration;
 
 4686    const char *mailboxuser;
 
 4687    const char *mailboxcontext;
 
 4688    const char *category;
 
 4693#define STORE_SQL_FMT_CAT "INSERT INTO %s (dir, msgnum, recording, context, callerid, " \ 
 4694    "origtime, duration, mailboxuser, mailboxcontext, flag, msg_id, category) " \ 
 4695    "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)" 
 4696#define STORE_SQL_FMT "INSERT INTO %s (dir, msgnum, recording, context, callerid, "\ 
 4697    "origtime, duration, mailboxuser, mailboxcontext, flag, msg_id) "\ 
 4698    "VALUES (?,?,?,?,?,?,?,?,?,?,?)" 
 4700static SQLHSTMT odbc_insert_data_cb(
struct odbc_obj *obj, 
void *vdata)
 
 4702    struct insert_data *data = vdata;
 
 4707    SCOPE_ENTER(3, 
"dir: %s msgnums: %s msg_id: %s\n", data->dir, data->msgnums,
 
 4710    res = SQLAllocHandle(SQL_HANDLE_STMT, obj->
con, &stmt);
 
 4711    if (!SQL_SUCCEEDED(res)) {
 
 4716    delete_sql = MAKE_SQL_PTRA(DELETE_SQL_FMT);
 
 4717    SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->dir), 0, (
void *) data->dir, 0, 
NULL);
 
 4718    SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->msgnums), 0, (
void *) data->msgnums, 0, 
NULL);
 
 4720    if (!SQL_SUCCEEDED(res)) {
 
 4721        ast_trace(-1, 
"There wasn't an existing row.  Good.\n");
 
 4723        ast_trace(-1, 
"There WAS an existing row. This is OK if we're replacing a message.\n");
 
 4725    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4728    res = SQLAllocHandle(SQL_HANDLE_STMT, obj->
con, &stmt);
 
 4729    if (!SQL_SUCCEEDED(res)) {
 
 4733    SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->dir), 0, (
void *) data->dir, 0, 
NULL);
 
 4734    SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->msgnums), 0, (
void *) data->msgnums, 0, 
NULL);
 
 4735    SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, data->datalen, 0, (
void *) data->data, data->datalen, &data->indlen);
 
 4736    SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->context), 0, (
void *) data->context, 0, 
NULL);
 
 4737    SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->callerid), 0, (
void *) data->callerid, 0, 
NULL);
 
 4738    SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->origtime), 0, (
void *) data->origtime, 0, 
NULL);
 
 4739    SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->duration), 0, (
void *) data->duration, 0, 
NULL);
 
 4740    SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->mailboxuser), 0, (
void *) data->mailboxuser, 0, 
NULL);
 
 4741    SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->mailboxcontext), 0, (
void *) data->mailboxcontext, 0, 
NULL);
 
 4742    SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->flag), 0, (
void *) data->flag, 0, 
NULL);
 
 4743    SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->msg_id), 0, (
void *) data->msg_id, 0, 
NULL);
 
 4745        insert_sql = MAKE_SQL_PTRA(STORE_SQL_FMT_CAT);
 
 4746        SQLBindParameter(stmt, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->category), 0, (
void *) data->category, 0, 
NULL);
 
 4748        insert_sql = MAKE_SQL_PTRA(STORE_SQL_FMT);
 
 4751    if (!SQL_SUCCEEDED(res)) {
 
 4754        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4774static int odbc_store_message(
const char *dir, 
const char *mailboxuser, 
const char *mailboxcontext, 
int msgnum)
 
 4778    void *fdm = MAP_FAILED;
 
 4782    char *fn = MAKE_FILE_PTRA(dir, msgnum);
 
 4783    char *full_fn = MAKE_FILE_EXT_PTRA(dir, msgnum, 
"txt");
 
 4788    struct insert_data idata = { .msgnums = msgnums, .dir = dir, .mailboxuser = mailboxuser, .mailboxcontext = mailboxcontext,
 
 4789        .context = 
"", .callerid = 
"", .origtime = 
"", .duration = 
"", .category = 
"", .flag = 
"", .msg_id = 
"" };
 
 4791    SCOPE_ENTER(3, 
"dir: %s user: %s context: %s msgnum: %d  msgtype: %s\n",
 
 4792        dir, mailboxuser, mailboxcontext, msgnum, msgnum < 0 ? 
"Greeting" : 
"Message");
 
 4801        c = strchr(fmt, 
'|');
 
 4804        if (!strcasecmp(fmt, 
"wav49"))
 
 4808        snprintf(msgnums, 
sizeof(msgnums), 
"%d", msgnum);
 
 4811        ast_trace(-1, 
"Opening '%s'\n", full_fn);
 
 4815                ast_trace(-1, 
"No information file found for '%s'.  This is a greeting so this is OK.\n", full_fn);
 
 4823        sprintf(full_fn, 
"%s.%s", fn, fmt); 
 
 4825            ast_trace(-1, 
"Audio stored on disk.  No need to open '%s'\n", full_fn);
 
 4827            ast_trace(-1, 
"Opening '%s'\n", full_fn);
 
 4828            fd = open(full_fn, O_RDWR);
 
 4837            ast_trace(-1, 
"Using information file '%s'\n", fn);
 
 4842                idata.callerid = 
"";
 
 4845                idata.origtime = 
"";
 
 4848                idata.duration = 
"";
 
 4851                idata.category = 
"";
 
 4862            ast_trace(-1, 
"Audio stored on disk.  Not reading sound file '%s' but setting magic number.\n", full_fn);
 
 4863            idata.data = AUDIO_ON_DISK_MAGIC;
 
 4864            idata.datalen = idata.indlen = AUDIO_ON_DISK_MAGIC_LEN;
 
 4866            ast_trace(-1, 
"Reading sound file '%s'\n", full_fn);
 
 4867            fdlen = lseek(fd, 0, SEEK_END);
 
 4868            if (fdlen < 0 || lseek(fd, 0, SEEK_SET) < 0) {
 
 4873            fdm = mmap(
NULL, fdlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 
 4874            if (fdm == MAP_FAILED) {
 
 4880            idata.datalen = idata.indlen = fdlen;
 
 4884            idata.origtime = 
"0";
 
 4888            idata.duration = 
"0";
 
 4892            SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4902    if (fdm != MAP_FAILED)
 
 4909#undef STORE_SQL_FMT_CAT 
 4924static void odbc_rename_message(
char *sdir, 
int smsg, 
char *mailboxuser, 
char *mailboxcontext, 
char *ddir, 
int dmsg)
 
 4927    char *sql = MAKE_SQL_PTRA(
"UPDATE %s SET dir=?, msgnum=? WHERE mailboxuser=? AND mailboxcontext=? AND dir=? AND msgnum=?");
 
 4931    char *argv[] = { ddir, msgnumd, mailboxuser, mailboxcontext, sdir, msgnums };
 
 4932    struct generic_prepare_struct gps = { .sql = sql, .argc = 6, .argv = argv };
 
 4933    SCOPE_ENTER(3, 
"sdir: %s smsg: %d user: %s context: %s ddir: %s dmsg: %d\n", sdir, smsg,
 
 4934        mailboxuser, mailboxcontext, ddir, dmsg);
 
 4936    SCOPE_CALL(-1, odbc_delete_message, ddir, dmsg);
 
 4943    snprintf(msgnums, 
sizeof(msgnums), 
"%d", smsg);
 
 4944    snprintf(msgnumd, 
sizeof(msgnumd), 
"%d", dmsg);
 
 4950        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 4954        char *src_fn = MAKE_FILE_PTRA(sdir, smsg);
 
 4955        char *dst_fn = MAKE_FILE_PTRA(ddir, dmsg);
 
 4957        ast_trace(-1, 
"Recordings stored on disk.  Renaming '%s' to '%s'\n", src_fn, dst_fn);
 
 4975static int odbc_remove_files(
char *dir, 
int msgnum)
 
 4977    char *fn = MAKE_FILE_PTRA(dir, msgnum);
 
 4978    char *full_fn = MAKE_FILE_EXT_PTRA(dir, msgnum, 
"txt");
 
 4979    SCOPE_ENTER(3, 
"dir: %s msgnum: %d\n", dir, msgnum);
 
 4982        ast_trace(-1, 
"Audio stored on disk.  Keeping '%s' sound files\n", fn);
 
 4984        ast_trace(-1, 
"Audio stored in ODBC.  Removing '%s' sound files\n", fn);
 
 4989    ast_trace(-1, 
"Removing '%s' information file\n", full_fn);
 
 5009    struct dirent *vment = 
NULL;
 
 5014    if ((vmdir = opendir(dir))) {
 
 5015        while ((vment = readdir(vmdir))) {
 
 5016            if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, 
".txt", 4)) {
 
 
 5039    snprintf(stxt, 
sizeof(stxt), 
"%s.txt", sfn);
 
 5040    snprintf(dtxt, 
sizeof(dtxt), 
"%s.txt", dfn);
 
 
 5062    struct dirent *msgdirent;
 
 5071    if (!(msgdir = opendir(dir))) {
 
 5075    while ((msgdirent = readdir(msgdir))) {
 
 5079            ast_debug(4, 
"%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount);
 
 5085        stopcount -= map[x];
 
 
 5104static int copy(
char *infile, 
char *outfile)
 
 5112#ifdef HARDLINK_WHEN_POSSIBLE 
 5114    if (!link(infile, outfile)) {
 
 5119    if ((ifd = open(infile, O_RDONLY)) < 0) {
 
 5144        wrlen = write(ofd, 
buf, 
len);
 
 
 5173    const char *origmailbox = 
"", *context = 
"", *exten = 
"";
 
 5174    const char *
priority = 
"", *callerchan = 
"", *callerid = 
"", *origdate = 
"";
 
 5175    const char *origtime = 
"", *category = 
"", *duration = 
"";
 
 5178    snprintf(frompath2, 
sizeof(frompath2), 
"%s.txt", frompath);
 
 5179    snprintf(topath2, 
sizeof(topath2), 
"%s.txt", topath);
 
 5184        for (tmp = 
var; tmp; tmp = tmp->
next) {
 
 5185            if (!strcasecmp(tmp->
name, 
"origmailbox")) {
 
 5186                origmailbox = tmp->
value;
 
 5187            } 
else if (!strcasecmp(tmp->
name, 
"context")) {
 
 5188                context = tmp->
value;
 
 5189            } 
else if (!strcasecmp(tmp->
name, 
"exten")) {
 
 5191            } 
else if (!strcasecmp(tmp->
name, 
"priority")) {
 
 5193            } 
else if (!strcasecmp(tmp->
name, 
"callerchan")) {
 
 5194                callerchan = tmp->
value;
 
 5195            } 
else if (!strcasecmp(tmp->
name, 
"callerid")) {
 
 5196                callerid = tmp->
value;
 
 5197            } 
else if (!strcasecmp(tmp->
name, 
"origdate")) {
 
 5198                origdate = tmp->
value;
 
 5199            } 
else if (!strcasecmp(tmp->
name, 
"origtime")) {
 
 5200                origtime = tmp->
value;
 
 5201            } 
else if (!strcasecmp(tmp->
name, 
"category")) {
 
 5202                category = tmp->
value;
 
 5203            } 
else if (!strcasecmp(tmp->
name, 
"duration")) {
 
 5204                duration = tmp->
value;
 
 5207        ast_store_realtime(
"voicemail_data", 
"filename", topath, 
"origmailbox", origmailbox, 
"context", context, 
"exten", exten, 
"priority", 
priority, 
"callerchan", callerchan, 
"callerid", callerid, 
"origdate", origdate, 
"origtime", origtime, 
"category", category, 
"duration", duration, 
SENTINEL);
 
 5209    copy(frompath2, topath2);
 
 
 5229    txtsize = (strlen(
file) + 5)*
sizeof(
char);
 
 5237    snprintf(txt, txtsize, 
"%s.txt", 
file);
 
 
 5245static void prep_email_sub_vars(
struct ast_channel *ast, 
struct ast_vm_user *vmu, 
int msgnum, 
char *context, 
char *mailbox, 
const char *fromfolder, 
char *cidnum, 
char *cidname, 
char *dur, 
char *date, 
const char *category, 
const char *
flag)
 
 5249    char fromdir[256], fromfile[256];
 
 5251    const char *origcallerid, *origtime;
 
 5252    char origcidname[80], origcidnum[80], origdate[80];
 
 5259    snprintf(num, 
sizeof(num), 
"%d", msgnum);
 
 5273    make_file(fromfile, 
sizeof(fromfile), fromdir, msgnum - 1);
 
 5274    if (strlen(fromfile) < 
sizeof(fromfile) - 5) {
 
 5275        strcat(fromfile, 
".txt");
 
 5278        ast_debug(1, 
"Config load for message text file '%s' failed\n", fromfile);
 
 5284        ast_callerid_split(origcallerid, origcidname, 
sizeof(origcidname), origcidnum, 
sizeof(origcidnum));
 
 5289    if ((origtime = 
ast_variable_retrieve(msg_cfg, 
"message", 
"origtime")) && sscanf(origtime, 
"%30d", &inttime) == 1) {
 
 5290        struct timeval tv = { inttime, };
 
 
 5313    for (ptr = from; *ptr; ptr++) {
 
 5314        if (*ptr == 
'"' || *ptr == 
'\\') {
 
 
 5355        if (*
str > 126 || *
str < 32 || strchr(
"()<>@,:;/\"[]?.=", *
str)) {
 
 
 5382    int first_section = 1;
 
 5386    for (; *start; start++) {
 
 5387        int need_encoding = 0;
 
 5388        if (*start < 33 || *start > 126 || strchr(
"()<>@,:;/\"[]?.=_", *start)) {
 
 5391        if ((first_section && need_encoding && preamble + 
ast_str_strlen(tmp) > 70) ||
 
 5392            (first_section && !need_encoding && preamble + 
ast_str_strlen(tmp) > 72) ||
 
 5394            (!first_section && !need_encoding && 
ast_str_strlen(tmp) > 72)) {
 
 5400        if (need_encoding && *start == 
' ') {
 
 5402        } 
else if (need_encoding) {
 
 
 5441        const char *fromfolder,
 
 5448        int attach_user_voicemail,
 
 5450        const char *category,
 
 5461    char enc_cidnum[256] = 
"", enc_cidname[256] = 
"";
 
 5463    char *greeting_attachment;
 
 5469    if (!str1 || !str2) {
 
 5481    gethostname(host, 
sizeof(host) - 1);
 
 5483    if (strchr(srcemail, 
'@')) {
 
 5486        snprintf(who, 
sizeof(who), 
"%s@%s", srcemail, host);
 
 5489    greeting_attachment = strrchr(
ast_strdupa(attach), 
'/');
 
 5490    if (greeting_attachment) {
 
 5491        *greeting_attachment++ = 
'\0';
 
 5494    snprintf(dur, 
sizeof(dur), 
"%d:%02d", duration / 60, duration % 60);
 
 5496    fprintf(p, 
"Date: %s" ENDL, date);
 
 5506            prep_email_sub_vars(ast, vmu, msgnum + 1, 
context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, 
flag);
 
 5528        fprintf(p, 
"From: Asterisk PBX <%s>" ENDL, who);
 
 5535        char *next = emailsbuf;
 
 5553        fprintf(p, 
"Subject: New greeting '%s' on %s." ENDL, greeting_attachment, date);
 
 5558            prep_email_sub_vars(ast, vmu, msgnum + 1, 
context, mailbox, fromfolder, cidnum, cidname, dur, date, category, 
flag);
 
 5581            fprintf(p, 
"Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
 
 5583            fprintf(p, 
"Subject: New %s message %d in mailbox %s" ENDL, 
flag, msgnum + 1, mailbox);
 
 5587            fprintf(p, 
"Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
 
 5589            fprintf(p, 
"Subject: [PBX]: New %s message %d in mailbox %s" ENDL, 
flag, msgnum + 1, mailbox);
 
 5593    fprintf(p, 
"Message-ID: <Asterisk-%d-%u-%s-%d@%s>" ENDL, msgnum + 1,
 
 5594        (
unsigned int) 
ast_random(), mailbox, (
int) getpid(), host);
 
 5597        fprintf(p, 
"X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
 
 5600        fprintf(p, 
"X-Asterisk-VM-Context: %s" ENDL, 
context);
 
 5602        fprintf(p, 
"X-Asterisk-VM-Extension: %s" ENDL, (!
ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox));
 
 5604        fprintf(p, 
"X-Asterisk-VM-Extension: %s" ENDL, mailbox);
 
 5607        fprintf(p, 
"X-Asterisk-VM-Flag: %s" ENDL, 
S_OR(
flag, 
""));
 
 5609        fprintf(p, 
"X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum);
 
 5610        fprintf(p, 
"X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname);
 
 5611        fprintf(p, 
"X-Asterisk-VM-Duration: %d" ENDL, duration);
 
 5613            fprintf(p, 
"X-Asterisk-VM-Category: %s" ENDL, category);
 
 5615            fprintf(p, 
"X-Asterisk-VM-Category: " ENDL);
 
 5617        fprintf(p, 
"X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? 
"Message" : greeting_attachment);
 
 5618        fprintf(p, 
"X-Asterisk-VM-Orig-date: %s" ENDL, date);
 
 5619        fprintf(p, 
"X-Asterisk-VM-Orig-time: %ld" ENDL, (
long) time(
NULL));
 
 5620        fprintf(p, 
"X-Asterisk-VM-Message-ID: %s" ENDL, msg_id);
 
 5623        fprintf(p, 
"X-Asterisk-CallerID: %s" ENDL, enc_cidnum);
 
 5626        fprintf(p, 
"X-Asterisk-CallerIDName: %s" ENDL, enc_cidname);
 
 5628    fprintf(p, 
"MIME-Version: 1.0" ENDL);
 
 5629    if (attach_user_voicemail) {
 
 5631        snprintf(bound, 
sizeof(bound), 
"----voicemail_%d%s%d%u", msgnum + 1, mailbox,
 
 5632            (
int) getpid(), (
unsigned int) 
ast_random());
 
 5634        fprintf(p, 
"Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
 
 5635        fprintf(p, 
ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
 
 5636        fprintf(p, 
"--%s" ENDL, bound);
 
 5638    fprintf(p, 
"Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, 
charset);
 
 5640        fprintf(p, 
"This message is to let you know that your greeting '%s' was changed on %s." ENDL 
 5641                "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL,
 
 5642                greeting_attachment, date);
 
 5647            prep_email_sub_vars(ast, vmu, msgnum + 1, 
context, mailbox, fromfolder, cidnum, cidname, dur, date, category, 
flag);
 
 5655                        if ((next = strchr(line, 
'\n'))) {
 
 5658                        fprintf(p, 
"%s" ENDL, line);
 
 5670        if (strcmp(vmu->
mailbox, mailbox)) {
 
 5675            char fromdir[256], fromfile[256], origdate[80] = 
"", origcallerid[80] = 
"";
 
 5679            make_file(fromfile, 
sizeof(fromfile), fromdir, msgnum);
 
 5680            if (strlen(fromfile) < 
sizeof(fromfile) - 5) {
 
 5681                strcat(fromfile, 
".txt");
 
 5690                if ((v = 
ast_variable_retrieve(msg_cfg, 
"message", 
"origtime")) && sscanf(v, 
"%30d", &inttime) == 1) {
 
 5691                    struct timeval tv = { inttime, };
 
 5696                fprintf(p, 
"Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 
 5697                    " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 
 5698                    "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 
 5700                    msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : 
"an unknown caller")),
 
 5701                    date, origcallerid, origdate);
 
 5708            fprintf(p, 
"Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 
 5709                "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 
 5710                "want to check it when you get a chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 
 5712                (cidname ? cidname : (cidnum ? cidnum : 
"an unknown caller")), date);
 
 5716    if (imap || attach_user_voicemail) {
 
 5718            snprintf(filename, 
sizeof(filename), 
"msg%04d.%s", msgnum, format);
 
 5719            ast_debug(5, 
"creating second attachment filename %s\n", filename);
 
 5720            add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum);
 
 5721            snprintf(filename, 
sizeof(filename), 
"msgintro%04d.%s", msgnum, format);
 
 5722            ast_debug(5, 
"creating attachment filename %s\n", filename);
 
 5723            add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum);
 
 5725            snprintf(filename, 
sizeof(filename), 
"msg%04d.%s", msgnum, format);
 
 5726            ast_debug(5, 
"creating attachment filename %s, no second attachment.\n", filename);
 
 5727            add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum);
 
 
 5738    char *file_to_delete = 
NULL, *dir_to_delete = 
NULL;
 
 5742    char altformat[80] = 
"";
 
 5746    char *mime_type = (!strcasecmp(format, 
"ogg")) ? 
"application/" : 
"audio/x-";
 
 5749    snprintf(fname, 
sizeof(fname), 
"%s.%s", attach, format);
 
 5752        c = strchr(altformat, 
'|');
 
 5757        snprintf(altfname, 
sizeof(altfname), 
"%s.%s", attach, altformat);
 
 5771        res = snprintf(sox_gain_tmpdir, 
sizeof(sox_gain_tmpdir), 
"%s/vm-gain-XXXXXX", tmpdir);
 
 5772        if (res >= 
sizeof(sox_gain_tmpdir)) {
 
 5773            ast_log(
LOG_ERROR, 
"Failed to create temporary directory path %s: Out of buffer space\n", tmpdir);
 
 5777        if (
mkdtemp(sox_gain_tmpdir)) {
 
 5781            ast_debug(3, 
"sox_gain_tmpdir: %s\n", sox_gain_tmpdir);
 
 5784            dir_to_delete = sox_gain_tmpdir;
 
 5786            res = snprintf(fname, 
sizeof(fname), 
"%s/output.%s", sox_gain_tmpdir, format);
 
 5787            if (res >= 
sizeof(fname)) {
 
 5788                ast_log(
LOG_ERROR, 
"Failed to create filename buffer for %s/output.%s: Too long\n", sox_gain_tmpdir, format);
 
 5793                res = snprintf(sox_gain_cmd, 
sizeof(sox_gain_cmd), 
"sox -v %.4f %s.%s %s",
 
 5794                               vmu->
volgain, attach, format, fname);
 
 5796                if (!strcasecmp(format, 
"wav")) {
 
 5798                        res = snprintf(sox_gain_cmd, 
sizeof(sox_gain_cmd), 
"sox -v %.4f %s.%s -e signed-integer -b 16 %s",
 
 5799                                       vmu->
volgain, attach, altformat, fname);
 
 5801                        res = snprintf(sox_gain_cmd, 
sizeof(sox_gain_cmd), 
"sox %s.%s -e signed-integer -b 16 %s",
 
 5802                                       attach, altformat, fname);
 
 5806                        res = snprintf(sox_gain_cmd, 
sizeof(sox_gain_cmd), 
"sox -v %.4f %s.%s %s",
 
 5807                                       vmu->
volgain, attach, altformat, fname);
 
 5809                        res = snprintf(sox_gain_cmd, 
sizeof(sox_gain_cmd), 
"sox %s.%s %s",
 
 5810                                       attach, altformat, fname);
 
 5815            if (res >= 
sizeof(sox_gain_cmd)) {
 
 5816                ast_log(
LOG_ERROR, 
"Failed to generate sox command, out of buffer space\n");
 
 5823                file_to_delete = fname;
 
 5824                ast_debug(3, 
"VOLGAIN: Stored at: %s - Level: %.4f - Mailbox: %s\n", fname, vmu->
volgain, mailbox);
 
 5826                ast_log(
LOG_WARNING, 
"Sox failed to re-encode %s: %s (have you installed support for all sox file formats?)\n",
 
 5828                        soxstatus == 1 ? 
"Problem with command line options" : 
"An error occurred during file processing");
 
 5836    if (!file_to_delete) {
 
 5837        res = snprintf(fname, 
sizeof(fname), 
"%s.%s", attach, format);
 
 5838        if (res >= 
sizeof(fname)) {
 
 5839            ast_log(
LOG_ERROR, 
"Failed to create filename buffer for %s.%s: Too long\n", attach, format);
 
 5844    fprintf(p, 
"--%s" ENDL, bound);
 
 5846        fprintf(p, 
"Content-Type: %s%s; name=\"%s\"" ENDL, mime_type, format, filename);
 
 5848        fprintf(p, 
"Content-Type: %s%s; name=\"%s.%s\"" ENDL, mime_type, format, greeting_attachment, format);
 
 5849    fprintf(p, 
"Content-Transfer-Encoding: base64" ENDL);
 
 5850    fprintf(p, 
"Content-Description: Voicemail sound attachment." ENDL);
 
 5852        fprintf(p, 
"Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename);
 
 5854        fprintf(p, 
"Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format);
 
 5859    if (file_to_delete) {
 
 5860        unlink(file_to_delete);
 
 5863    if (dir_to_delete) {
 
 5864        rmdir(dir_to_delete);
 
 
 5875        const char *fromfolder,
 
 5882        int attach_user_voicemail,
 
 5884        const char *category,
 
 5889    char tmp[80] = 
"/tmp/astmail-XXXXXX";
 
 5903    if (!strcmp(format, 
"wav49"))
 
 5912        make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, 
flag, msg_id);
 
 5914        snprintf(tmp2, 
sizeof(tmp2), 
"( %s < %s ; rm -f %s ) &", 
mailcmd, tmp, tmp);
 
 
 5921static int sendpage(
char *srcemail, 
char *pager, 
int msgnum, 
char *context, 
char *mailbox, 
const char *fromfolder, 
char *cidnum, 
char *cidname, 
int duration, 
struct ast_vm_user *vmu, 
const char *category, 
const char *
flag)
 
 5923    char enc_cidnum[256], enc_cidname[256];
 
 5928    char tmp[80] = 
"/tmp/astmail-XXXXXX";
 
 5934    if (!str1 || !str2) {
 
 5953    gethostname(host, 
sizeof(host)-1);
 
 5954    if (strchr(srcemail, 
'@')) {
 
 5957        snprintf(who, 
sizeof(who), 
"%s@%s", srcemail, host);
 
 5959    snprintf(dur, 
sizeof(dur), 
"%d:%02d", duration / 60, duration % 60);
 
 5961    fprintf(p, 
"Date: %s\n", date);
 
 5970            prep_email_sub_vars(ast, vmu, msgnum + 1, 
context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, 
flag);
 
 5992        fprintf(p, 
"From: Asterisk PBX <%s>" ENDL, who);
 
 6014            prep_email_sub_vars(ast, vmu, msgnum + 1, 
context, mailbox, fromfolder, cidnum, cidname, dur, date, category, 
flag);
 
 6037            fprintf(p, 
"Subject: New VM" ENDL);
 
 6039            fprintf(p, 
"Subject: New %s VM" ENDL, 
flag);
 
 6049            prep_email_sub_vars(ast, vmu, msgnum + 1, 
context, mailbox, fromfolder, cidnum, cidname, dur, date, category, 
flag);
 
 6057        fprintf(p, 
"New %s long %s msg in box %s\n" 
 6058                "from %s, on %s", dur, 
flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : 
"unknown")), date);
 
 6062    snprintf(tmp2, 
sizeof(tmp2), 
"( %s < %s ; rm -f %s ) &", 
mailcmd, tmp, tmp);
 
 
 6095    snprintf(fn, 
sizeof(fn), 
"%s%s/%s/greet", 
VM_SPOOL_DIR, context, 
ext);
 
 
 6129#define COUNT_MSGS_SQL_FMT "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'" 
 6130static int count_messages_in_folder(
struct odbc_obj *odbc, 
const char *context, 
const char *mailbox, 
const char *folder, 
int *messages)
 
 6133    char sql[
sizeof(COUNT_MSGS_SQL_FMT) + odbc_table_len + strlen(
VM_SPOOL_DIR)
 
 6134             + strlen(context) + strlen(mailbox) + strlen(folder)];
 
 6136    SQLHSTMT stmt = 
NULL;
 
 6137    struct generic_prepare_struct gps = { .sql = sql, .argc = 0 };
 
 6138    SCOPE_ENTER(3, 
"context: %s  mb: %s  folder: %s", context, mailbox, folder);
 
 6144    snprintf(sql, 
sizeof(sql), COUNT_MSGS_SQL_FMT, odbc_table, 
VM_SPOOL_DIR, context, mailbox, folder);
 
 6148    res = SQLFetch(stmt);
 
 6149    if (!SQL_SUCCEEDED(res)) {
 
 6150        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 6153    res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, 
sizeof(rowdata), 
NULL);
 
 6154    if (!SQL_SUCCEEDED(res)) {
 
 6155        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 6159    *messages = atoi(rowdata);
 
 6160    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 6164#undef COUNT_MSGS_SQL_FMT 
 6166static int inboxcount2(
const char *mailbox, 
int *urgentmsgs, 
int *newmsgs, 
int *oldmsgs)
 
 6187    if (strchr(mailbox, 
' ') || strchr(mailbox, 
',')) {
 
 6189        char *
next, *remaining = tmp;
 
 6204        SCOPE_EXIT_RTN_VALUE(0, 
"Urgent: %d  New: %d  Old: %d\n", urgentmsgs ? *urgentmsgs : 0, newmsgs ? *newmsgs : 0, oldmsgs ? *oldmsgs : 0);
 
 6219    if (count_messages_in_folder(obj, context, tmp, 
"INBOX", newmsgs)
 
 6220       || count_messages_in_folder(obj, context, tmp, 
"Old", oldmsgs)
 
 6221       || count_messages_in_folder(obj, context, tmp, 
"Urgent", urgentmsgs)) {
 
 6227    SCOPE_EXIT_RTN_VALUE(0, 
"Urgent: %d  New: %d  Old: %d\n", urgentmsgs ? *urgentmsgs : 0, newmsgs ? *newmsgs : 0, oldmsgs ? *oldmsgs : 0);
 
 6238#define MSGCOUNT_SQL_FMT_INBOX "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/INBOX' OR dir = '%s%s/%s/Urgent'" 
 6239#define MSGCOUNT_SQL_FMT "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'" 
 6240static int messagecount(
const char *mailbox_id, 
const char *folder)
 
 6247    SQLHSTMT stmt = 
NULL;
 
 6249    struct generic_prepare_struct gps = { .argc = 0 };
 
 6250    SCOPE_ENTER(3, 
"mb: %s  folder: %s", mailbox_id, folder);
 
 6267    if (!strcmp(folder, 
"INBOX")) {
 
 6282    res = SQLFetch(stmt);
 
 6283    if (!SQL_SUCCEEDED(res)) {
 
 6285        goto bail_with_handle;
 
 6287    res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, 
sizeof(rowdata), 
NULL);
 
 6288    if (!SQL_SUCCEEDED(res)) {
 
 6290        goto bail_with_handle;
 
 6292    nummsgs = atoi(rowdata);
 
 6295    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 6302#undef MSGCOUNT_SQL_FMT 
 6303#undef MSGCOUNT_SQL_FMT_INBOX 
 6319    while ((mailbox = 
strsep(&parse, 
",&"))) {
 
 6345    long duration, 
struct ast_vm_user *recip, 
char *fmt, 
char *dir, 
const char *
flag,
 
 6346    const char *dest_folder)
 
 6349    const char *frombox = 
mbox(vmu, imbox);
 
 6350    const char *userfolder;
 
 6353    SCOPE_ENTER(3, 
"mb: %s  imb: %d  msgnum: %d recip: %s dir: %s dest_folder: %s",
 
 6359        userfolder = 
"Urgent";
 
 6361        userfolder = dest_folder;
 
 6363        userfolder = 
"INBOX";
 
 6374    ast_trace(-1, 
"fromdir: %s\n", fromdir);
 
 6376    make_file(frompath, 
sizeof(frompath), fromdir, msgnum);
 
 6377    ast_trace(-1, 
"frompath: %s\n", frompath);
 
 6387    ast_trace(-1, 
"recip msgnum: %d\n", recipmsgnum);
 
 6392        make_file(topath, 
sizeof(topath), todir, recipmsgnum);
 
 6400            SCOPE_CALL(-1, 
STORE, todir, recip->
mailbox, recip->
context, recipmsgnum, chan, recip, fmt, duration, 
NULL, 
NULL, 
NULL);
 
 
 6420#if !(defined(IMAP_STORAGE) || defined(ODBC_STORAGE)) 
 6435static int __has_voicemail(
const char *context, 
const char *mailbox, 
const char *folder, 
int shortcircuit)
 
 6452        context = 
"default";
 
 6454    c = (
char *)context;
 
 6468    snprintf(fn, 
sizeof(fn), 
"%s%s/%s/%s", 
VM_SPOOL_DIR, 
c, m, folder);
 
 6470    if (!(dir = opendir(fn)))
 
 6473    while ((de = readdir(dir))) {
 
 6474        if (!strncasecmp(de->d_name, 
"msg", 3)) {
 
 6478            } 
else if (!strncasecmp(de->d_name + 8, 
"txt", 3)) {
 
 
 6500    char tmp[256], *tmp2 = tmp, *box, *context;
 
 6505    while ((box = 
strsep(&tmp2, 
",&"))) {
 
 6506        if ((context = strchr(box, 
'@')))
 
 6509            context = 
"default";
 
 6513        if (!strcmp(folder, 
"INBOX") && 
__has_voicemail(context, box, 
"Urgent", 1)) {
 
 
 6549        int tmpnew, tmpold, tmpurgent;
 
 6554        while ((cur = 
strsep(&mb, 
", "))) {
 
 6566                        *urgentmsgs += tmpurgent;
 
 6576    if ((context = strchr(tmp, 
'@'))) {
 
 6579        context = 
"default";
 
 
 6603        *newmsgs += urgentmsgs;
 
 
 6610    char arguments[255];
 
 6611    char ext_context[256] = 
"";
 
 6612    int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0;
 
 6616        snprintf(ext_context, 
sizeof(ext_context), 
"%s@%s", 
extension, context);
 
 6628            if (!strncmp(mwi_msg->
cause, 
"INV", 3))
 
 6630            else if (!strncmp(mwi_msg->
cause, 
"BLK", 3))
 
 6640        if (
inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) {
 
 6643            snprintf(arguments, 
sizeof(arguments), 
"%s %s %s %d %d %d &",
 
 6646                oldvoicemails, urgentvoicemails);
 
 6647            ast_debug(1, 
"Executing %s\n", arguments);
 
 
 6672    snprintf(dst, 
MSG_ID_LEN, 
"%ld-%08x", (
long) time(
NULL), unique_counter);
 
 
 6706    char ext_context[256] = 
"";
 
 6722    const char *category = 
NULL; 
 
 6731    memset(&svm, 0, 
sizeof(svm));
 
 6743                duration = (int) (framelength / sample_rate);
 
 6752    if (duration < recipient->minsecs) {
 
 6753        ast_log(
LOG_NOTICE, 
"Copying recording to voicemail %s@%s skipped because duration was shorter than " 
 6754                    "minmessage of recipient\n", recdata->
mailbox, recdata->
context);
 
 6764    snprintf(tmptxtfile, 
sizeof(tmptxtfile), 
"%s/XXXXXX", tmpdir);
 
 6765    txtdes = mkstemp(tmptxtfile);
 
 6775    txt = fdopen(txtdes, 
"w+");
 
 6781            "; Message Information file\n" 
 6804            date, (
long) time(
NULL),
 
 6829    snprintf(ext_context, 
sizeof(ext_context), 
"%s@%s", recipient->
mailbox, recipient->
context);
 
 6833    res = 
inboxcount(ext_context, &newmsgs, &oldmsgs);
 
 6840    if (!(vms = get_vm_state_by_mailbox(recipient->
mailbox, recipient->
context, 0))) {
 
 6845        if (!(vms = create_vm_state_from_user(recipient))) {
 
 6855    msgnum = newmsgs + oldmsgs;
 
 6856    ast_debug(3, 
"Messagecount set to %d\n", msgnum);
 
 6857    snprintf(destination, 
sizeof(destination), 
"%simap/msg%s%04d", 
VM_SPOOL_DIR, recipient->
mailbox, msgnum);
 
 6861    if ((res = imap_check_limits(
NULL, vms, recipient, msgnum))) {
 
 6872    ast_debug(3, 
"mailbox = %d : inprocess = %d\n", 
COUNT(recipient, dir),
 
 6888        ast_log(
LOG_ERROR, 
"Couldn't lock directory %s.  Voicemail will be lost.\n", dir);
 
 6896    make_file(destination, 
sizeof(destination), dir, msgnum);
 
 6898    make_file(tmpaudiofile, 
sizeof(tmpaudiofile), tmpdir, msgnum);
 
 6901        ast_log(
LOG_ERROR, 
"Audio file failed to copy to tmp dir. Probably low disk space.\n");
 
 6912        ast_log(
LOG_ERROR, 
"Audio file failed to move to destination directory. Permissions/Overlap?\n");
 
 6920    snprintf(desttxtfile, 
sizeof(desttxtfile), 
"%s.txt", destination);
 
 6921    rename(tmptxtfile, desttxtfile);
 
 6938        char cidnum[80], cidname[80];
 
 6944                "origmailbox", recdata->
mailbox,
 
 6951                "origtime", time(
NULL),
 
 6952                "category", 
S_OR(category, 
""),
 
 6953                "filename", tmptxtfile,
 
 6954                "duration", duration,
 
 6958        STORE(dir, recipient->
mailbox, recipient->
context, msgnum, 
NULL, recipient, fmt, 0, vms, 
"", msg_id);
 
 
 7000    int newmsgs, oldmsgs;
 
 7012    int sound_duration = 0;
 
 7014    int greeting_only = 0;
 
 7023    char ext_context[256] = 
"";
 
 7026    char ecodes[17] = 
"#";
 
 7031    const char *category = 
NULL;
 
 7033    const char *alldtmf = 
"0123456789ABCD*#";
 
 7045        tmpptr = strchr(
context, 
'&');
 
 7047        tmpptr = strchr(
ext, 
'&');
 
 7068    memset(&svm, 0, 
sizeof(svm));
 
 7083    if (strcmp(vmu->
context, 
"default"))
 
 7084        snprintf(ext_context, 
sizeof(ext_context), 
"%s@%s", 
ext, vmu->
context);
 
 7098    ast_trace(-1, 
"prefile: %s\n", prefile);
 
 7104    ast_trace(-1, 
"tempfile: %s\n", tempfile);
 
 7114        ast_trace(-1, 
"new prefile: %s\n", prefile);
 
 7134                strncat(ecodes, 
"0", 
sizeof(ecodes) - strlen(ecodes) - 1);
 
 7139            strncat(ecodes, 
"0", 
sizeof(ecodes) - strlen(ecodes) - 1);
 
 7147            strncat(ecodes, 
"*", 
sizeof(ecodes) - strlen(ecodes) - 1);
 
 7151        strncat(ecodes, 
"*", 
sizeof(ecodes) - strlen(ecodes) - 1);
 
 7155        for (code = alldtmf; *code; code++) {
 
 7158            if (strchr(ecodes, e[0]) == 
NULL 
 7162                strncat(ecodes, e, 
sizeof(ecodes) - strlen(ecodes) - 1);
 
 7169#if defined(ODBC_STORAGE) 
 7171#elif defined(IMAP_STORAGE) 
 7185            if (success == -1) {
 
 7187                ast_trace(-1, 
"Greeting '%s' not retrieved from database, but found in file storage. Inserting into database\n", prefile);
 
 7192            ast_trace(-1, 
"%s doesn't exist, doing what we can\n", prefile);
 
 7259    if (greeting_only) {
 
 7260        ast_debug(3, 
"Greetings only VM (maxmsg=0), Skipping voicemail recording\n");
 
 7284        res = 
inboxcount(ext_context, &newmsgs, &oldmsgs);
 
 7291        if (!(vms = get_vm_state_by_mailbox(
ext, 
context, 0))) {
 
 7296            if (!(vms = create_vm_state_from_user(vmu))) {
 
 7306        msgnum = newmsgs + oldmsgs;
 
 7307        ast_debug(3, 
"Messagecount set to %d\n", msgnum);
 
 7312        if ((res = imap_check_limits(chan, vms, vmu, msgnum))) {
 
 7327        snprintf(tmptxtfile, 
sizeof(tmptxtfile), 
"%s/XXXXXX", tmpdir);
 
 7328        ast_trace(-1, 
"Tempfile: %s\n", tmptxtfile);
 
 7329        txtdes = mkstemp(tmptxtfile);
 
 7353            snprintf(origtime, 
sizeof(origtime), 
"%ld", (
long) time(
NULL));
 
 7365                "callerid", callerid,
 
 7367                "origtime", origtime,
 
 7368                "category", 
S_OR(category, 
""),
 
 7369                "filename", tmptxtfile,
 
 7374        txt = fdopen(txtdes, 
"w+");
 
 7384                "; Message Information file\n" 
 7406                date, (
long) time(
NULL),
 
 7407                category ? category : 
"",
 
 7409            ast_trace(-1, 
"Saving txt file mbox: %s msg_id: %s\n", 
ext, msg_id);
 
 7420        res = 
SCOPE_CALL_WITH_INT_RESULT(-1, 
play_record_review, chan, 
NULL, tmptxtfile, vmu->
maxsecs, fmt, 1, vmu, &duration, &sound_duration, 
NULL, 
options->record_gain, vms, 
flag, msg_id, 0);
 
 7426        if (!strcmp(
flag, 
"Urgent")) {
 
 7431            fprintf(txt, 
"flag=%s\n", 
flag);
 
 7432            if (sound_duration < vmu->
minsecs) {
 
 7434                ast_verb(3, 
"Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->
minsecs);
 
 7442                fprintf(txt, 
"duration=%d\n", duration);
 
 7451                    ast_debug(1, 
"The recorded media file is gone, so we should remove the .txt file too!\n");
 
 7471                    snprintf(txtfile, 
sizeof(txtfile), 
"%s.txt", fn);
 
 7473                    ast_trace(-1, 
"Renaming recordings '%s' -> fn '%s'\n", tmptxtfile, fn);
 
 7477                    ast_trace(-1, 
"Renaming txt file '%s' -> fn '%s'\n", tmptxtfile, txtfile);
 
 7478                    rename(tmptxtfile, txtfile);
 
 7488                        snprintf(tmpdur, 
sizeof(tmpdur), 
"%d", duration);
 
 7495                        SCOPE_CALL(-1, 
STORE, dir, vmu->
mailbox, vmu->
context, msgnum, chan, vmu, fmt, duration, vms, 
flag, msg_id);
 
 7503                        exten = 
strsep(&tmpptr, 
"&");
 
 7504                        cntx = strchr(exten, 
'@');
 
 7509                        memset(&recipu, 0, 
sizeof(recipu));
 
 7510                        if ((recip = 
find_user(&recipu, cntx, exten))) {
 
 7542        } 
else if (res > 0 && res != 
't')
 
 7545        if (sound_duration < vmu->
minsecs)
 
 7557    ast_debug(3, 
"*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup);
 
 7558    if (expungeonhangup == 1 && vms->mailstream != 
NULL) {
 
 7560#ifdef HAVE_IMAP_TK2006 
 7561        if (LEVELUIDPLUS (vms->mailstream)) {
 
 7562            mail_expunge_full(vms->mailstream, NIL, EX_UID);
 
 7565            mail_expunge(vms->mailstream);
 
 
 7574#if !defined(IMAP_STORAGE) 
 7587    for (x = 0, dest = 0; dest != stopcount && x < 
MAXMSGLIMIT; x++) {
 
 
 7623    snprintf(sequence, 
sizeof(sequence), 
"%ld", vms->msgArray[msg]);
 
 7625    ast_debug(3, 
"Copying sequence %s to mailbox %s\n", sequence, 
mbox(vmu, box));
 
 7629        mail_setflag(vms->mailstream, sequence, 
"\\Seen");
 
 7631        mail_clearflag(vms->mailstream, sequence, 
"\\Seen");
 
 7643    if (vms->mailstream && !mail_status(vms->mailstream, 
mailbox, SA_UIDNEXT)) {
 
 7644            if (mail_create(vms->mailstream, 
mailbox) != NIL) {
 
 7650    if (init_mailstream(vms, curr_mbox) || !vms->mailstream) {
 
 7655            res = !mail_move(vms->mailstream, sequence, (
char *) 
mbox(vmu, box));
 
 7657            res = !mail_copy(vms->mailstream, sequence, (
char *) 
mbox(vmu, box));
 
 7669    const char *dbox = 
mbox(vmu, box);
 
 7671    SCOPE_ENTER(3, 
"dir: %s msg: %d  box: %d  dbox: %s  move? %d  \n", dir, msg, box, dbox, move);
 
 7683        ast_trace(-1, 
"Deleting message %d\n", msg);
 
 7685        for (i = 1; i <= x; i++) {
 
 7688            make_file(dfn, 
sizeof(dfn), ddir, i - 1);
 
 7702    if (strcmp(sfn, dfn)) {
 
 7703        ast_trace(-1, 
"Copying message '%s' to '%s'\n", sfn, dfn);
 
 
 7725    unsigned char buf[256];
 
 7757    bytes += ast_adsi_logo(
buf);
 
 7801    for (x = 0; x < 5; x++) {
 
 7802        snprintf(num, 
sizeof(num), 
"%d", x);
 
 7830    ast_debug(1, 
"Done downloading scripts...\n");
 
 7838    ast_debug(1, 
"Restarting session...\n");
 
 
 7874    unsigned char buf[256];
 
 7876    unsigned char keys[8];
 
 7881    for (x = 0; x < 8; x++)
 
 
 7900    unsigned char buf[256];
 
 7902    unsigned char keys[8];
 
 7907    for (x = 0; x < 8; x++)
 
 
 7922    unsigned char buf[256];
 
 7924    unsigned char keys[8];
 
 7930    for (x = 0; x < 5; x++) {
 
 
 7952    unsigned char buf[256];
 
 7953    char buf1[256], buf2[256];
 
 7959    char datetime[21] = 
"";
 
 7962    unsigned char keys[8];
 
 7970    snprintf(fn2, 
sizeof(fn2), 
"%s.txt", vms->
fn);
 
 7971    f = fopen(fn2, 
"r");
 
 7974            if (!fgets((
char *) 
buf, 
sizeof(
buf), f)) {
 
 7978                char *stringp = 
NULL;
 
 7979                stringp = (
char *) 
buf;
 
 7983                    if (!strcmp((
char *) 
buf, 
"callerid"))
 
 7985                    if (!strcmp((
char *) 
buf, 
"origdate"))
 
 7993    for (x = 0; x < 5; x++)
 
 8020        name = 
"Unknown Caller";
 
 8036    snprintf(buf1, 
sizeof(buf1), 
"%s%s", vms->
curbox,
 
 8037        strcasecmp(vms->
curbox, 
"INBOX") ? 
" Messages" : 
"");
 
 8038    snprintf(buf2, 
sizeof(buf2), 
"Message %d of %d", vms->
curmsg + 1, vms->
lastmsg + 1);
 
 
 8054    unsigned char buf[256];
 
 8055    unsigned char keys[8];
 
 8063    for (x = 0; x < 5; x++)
 
 
 8105    unsigned char buf[256] = 
"";
 
 8106    char buf1[256] = 
"", buf2[256] = 
"";
 
 8108    unsigned char keys[8];
 
 8111    char *newm = (vms->
newmessages == 1) ? 
"message" : 
"messages";
 
 8112    char *oldm = (vms->
oldmessages == 1) ? 
"message" : 
"messages";
 
 8116        snprintf(buf1, 
sizeof(buf1), 
"You have %d new", vms->
newmessages);
 
 8118            strncat(buf1, 
" and", 
sizeof(buf1) - strlen(buf1) - 1);
 
 8119            snprintf(buf2, 
sizeof(buf2), 
"%d old %s.", vms->
oldmessages, oldm);
 
 8121            snprintf(buf2, 
sizeof(buf2), 
"%s.", newm);
 
 8124        snprintf(buf1, 
sizeof(buf1), 
"You have %d old", vms->
oldmessages);
 
 8125        snprintf(buf2, 
sizeof(buf2), 
"%s.", oldm);
 
 8127        strcpy(buf1, 
"You have no messages.");
 
 8135    for (x = 0; x < 6; x++)
 
 
 8152    unsigned char buf[256] = 
"";
 
 8153    char buf1[256] = 
"", buf2[256] = 
"";
 
 8155    unsigned char keys[8];
 
 8158    char *mess = (vms->
lastmsg == 0) ? 
"message" : 
"messages";
 
 8164    for (x = 0; x < 6; x++)
 
 8173    snprintf(buf1, 
sizeof(buf1), 
"%s%s has", vms->
curbox,
 
 8174        strcasecmp(vms->
curbox, 
"INBOX") ? 
" folder" : 
"");
 
 8177        snprintf(buf2, 
sizeof(buf2), 
"%d %s.", vms->
lastmsg + 1, mess);
 
 8179        strcpy(buf2, 
"no messages.");
 
 
 8208    unsigned char buf[256];
 
 
 8234    for (x = start; x < 5; x++) {   
 
 8240        snprintf(fn, 
sizeof(fn), 
"vm-%s", 
mbox(
NULL, x));   
 
 8249                ast_verb(4, 
"Failed to find file %s; falling back to INBOX\n", fn);
 
 
 8277    for (x = start; x < 5; x++) {    
 
 8281        snprintf(fn, 
sizeof(fn), 
"vm-%s", 
mbox(
NULL, x));     
 
 
 8317    while (((res < 
'0') || (res > 
'9')) &&
 
 8318           (res != 
'#') && (res >= 0) &&
 
 8333        isprint(res) ? res : 
'?', isprint(res) ? res : 
'?');
 
 
 8356    int curmsg, 
char *vm_fmts, 
char *
context, 
signed char record_gain, 
long *duration,
 
 8360    int retries = 0, prepend_duration = 0, already_recorded = 0;
 
 8366    signed char zero_gain = 0;
 
 8368    const char *msg_id = 
NULL;
 
 8370    const char *duration_str;
 
 8374    make_file(msgfile, 
sizeof(msgfile), curdir, curmsg);
 
 8375    ast_trace(-1, 
"msgfile: %s\n", msgfile);
 
 8376    strcpy(textfile, msgfile);
 
 8377    strcpy(backup, msgfile);
 
 8378    strcpy(backup_textfile, msgfile);
 
 8379    strncat(textfile, 
".txt", 
sizeof(textfile) - strlen(textfile) - 1);
 
 8380    strncat(backup, 
"-bak", 
sizeof(backup) - strlen(backup) - 1);
 
 8381    strncat(backup_textfile, 
"-bak.txt", 
sizeof(backup_textfile) - strlen(backup_textfile) - 1);
 
 8384        *duration = atoi(duration_str);
 
 8389    while ((cmd >= 0) && (cmd != 
't') && (cmd != 
'*')) {
 
 8400            make_file(vms->introfn, 
sizeof(vms->introfn), curdir, curmsg);
 
 8401            strncat(vms->introfn, 
"intro", 
sizeof(vms->introfn));
 
 8404            cmd = 
play_record_review(chan, 
NULL, vms->introfn, vmu->
maxsecs, vm_fmts, 1, vmu, (
int *) duration, 
NULL, 
NULL, record_gain, vms, 
flag, msg_id, 1);
 
 8412            ast_trace(-1, 
"Prepending to message %d\n", curmsg);
 
 8414            make_file(msgfile, 
sizeof(msgfile), curdir, curmsg);
 
 8415            ast_trace(-1, 
"msgfile: %s\n", msgfile);
 
 8417            strcpy(textfile, msgfile);
 
 8418            strncat(textfile, 
".txt", 
sizeof(textfile) - 1);
 
 8429            if (already_recorded) {
 
 8430                ast_trace(-1, 
"Restoring '%s' to '%s'\n", backup, msgfile);
 
 8432                copy(backup_textfile, textfile);
 
 8435                ast_trace(-1, 
"Backing up '%s' to '%s'\n", backup, msgfile);
 
 8437                copy(textfile, backup_textfile);
 
 8440            already_recorded = 1;
 
 8445            cmd = 
SCOPE_CALL_WITH_INT_RESULT(-1, 
ast_play_and_prepend, chan, 
NULL, msgfile, 0, vm_fmts, &prepend_duration, 
NULL, 1, 
silencethreshold, 
maxsilence);
 
 8458                *duration = atoi(duration_str);
 
 8460            if (prepend_duration) {
 
 8463                char duration_buf[12];
 
 8465                *duration += prepend_duration;
 
 8466                ast_trace(-1, 
"Prepending duration: %d  total duration: %ld\n", prepend_duration, *duration);
 
 8468                snprintf(duration_buf, 
sizeof(duration_buf), 
"%ld", *duration);
 
 8479            *vms->introfn = 
'\0';
 
 8488            already_recorded = 0;
 
 8506                isprint(cmd) ? cmd : 
'?', isprint(cmd) ? cmd : 
'?');
 
 8512    if (prepend_duration)
 
 8513        *duration = prepend_duration;
 
 8515    if (already_recorded && cmd == -1) {
 
 8517        ast_trace(-1, 
"Restoring '%s' to '%s'\n", backup, msgfile);
 
 8519        rename(backup_textfile, textfile);
 
 8522    if (cmd == 
't' || cmd == 
'S') { 
 
 
 8528static void queue_mwi_event(
const char *channel_id, 
const char *box, 
int urgent, 
int new, 
int old)
 
 8537    ast_debug(3, 
"Queueing event for mailbox %s  New: %d   Old: %d\n", box, 
new + urgent, old);
 
 8550            ast_debug(3, 
"Found alias mapping: %s -> %s\n", mapping->
alias, box);
 
 
 8576    int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;
 
 8577    const char *category;
 
 8589    snprintf(todir, 
sizeof(todir), 
"%simap", 
VM_SPOOL_DIR);
 
 8591    make_file(fn, 
sizeof(fn), todir, msgnum);
 
 8592    snprintf(ext_context, 
sizeof(ext_context), 
"%s@%s", vmu->
mailbox, vmu->
context);
 
 8611        char *msg_id = 
NULL;
 
 8617        snprintf(filename, 
sizeof(filename), 
"%s.txt", fn);
 
 8625        if (attach_user_voicemail)
 
 8629        sendmail(myserveremail, vmu, msgnum, vmu->
context, vmu->
mailbox, 
mbox(vmu, 0), cidnum, cidname, fn, 
NULL, fmt, duration, attach_user_voicemail, chan, category, 
flag, msg_id);
 
 8631        if (attach_user_voicemail)
 
 8636        sendpage(myserveremail, vmu->
pager, msgnum, vmu->
context, vmu->
mailbox, 
mbox(vmu, 0), cidnum, cidname, duration, vmu, category, 
flag);
 
 8640        DELETE(todir, msgnum, fn, vmu);
 
 
 8695    char ecodes[16] = 
"#";
 
 8696    int res = 0, cmd = 0;
 
 8701    const char mailbox_context[256];
 
 8702    int saved_messages = 0;
 
 8703    int valid_extensions = 0;
 
 8706    char urgent_str[7] = 
"";
 
 8707    int prompt_played = 0;
 
 8715        ast_copy_string(urgent_str, urgent ? 
"Urgent" : 
"", 
sizeof(urgent_str));
 
 8725    while (!res && !valid_extensions) {
 
 8726        int use_directory = 0;
 
 8731            while ((cmd >= 0) && !
done ){
 
 8761                        isprint(cmd) ? cmd : 
'?', isprint(cmd) ? cmd : 
'?');
 
 8764            if (cmd < 0 || cmd == 
't')
 
 8768        if (use_directory) {
 
 8771            struct ast_app* directory_app;
 
 8774            if (directory_app) {
 
 8775                char vmcontext[256];
 
 8785                snprintf(vmcontext, 
sizeof(vmcontext), 
"%s,,v", context ? context : 
"default");
 
 8786                res = 
pbx_exec(chan, directory_app, vmcontext);
 
 8802            if (res || prompt_played > 4)
 
 8804            if ((res = 
ast_readstring(chan, username, 
sizeof(username) - 1, 2000, 10000, 
"#")) < 0)
 
 8812        s = 
strsep(&stringp, 
"*");
 
 8814        valid_extensions = 1;
 
 8816            snprintf((
char*)mailbox_context, 
sizeof(mailbox_context), 
"%s@%s", s, context ? context : 
"default");
 
 8817            if ((is_new_message == 1 || strcmp(s, sender->
mailbox)) && (receiver = 
find_user(
NULL, context, s))) {
 
 8822                if (
inboxcount(mailbox_context, &newmsgs, &oldmsgs)) {
 
 8823                    ast_log(
LOG_ERROR, 
"Problem in calculating number of voicemail messages available for extension %s\n", mailbox_context);
 
 8826                    valid_extensions = 0;
 
 8830                if (!(dstvms = get_vm_state_by_mailbox(s, context, 0))) {
 
 8831                    if (!(dstvms = create_vm_state_from_user(receiver))) {
 
 8835                        valid_extensions = 0;
 
 8839                check_quota(dstvms, imapfolder);
 
 8840                if (dstvms->quota_limit && dstvms->quota_usage >= dstvms->quota_limit) {
 
 8841                    ast_log(
LOG_NOTICE, 
"Mailbox '%s' is exceeded quota %u >= %u\n", mailbox_context, dstvms->quota_usage, dstvms->quota_limit);
 
 8843                    valid_extensions = 0;
 
 8852                if ((newmsgs + oldmsgs) >= capacity) {
 
 8853                    ast_log(
LOG_NOTICE, 
"Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", mailbox_context, capacity);
 
 8855                    valid_extensions = 0;
 
 8876                valid_extensions = 0;
 
 8894            s = 
strsep(&stringp, 
"*");
 
 8897        if (valid_extensions)
 
 8903    if (is_new_message == 1) {
 
 8906        snprintf(mailbox, 
sizeof(mailbox), 
"%s@%s", username, context);
 
 8909        memset(&leave_options, 0, 
sizeof(leave_options));
 
 8917        int copy_msg_result = 0;
 
 8921        const char *msg_id = 
NULL;
 
 8924        memcpy(&vmstmp, vms, 
sizeof(vmstmp));
 
 8928        make_file(filename, 
sizeof(filename), dir, curmsg);
 
 8929        strncat(filename, 
".txt", 
sizeof(filename) - strlen(filename) - 1);
 
 8937        cmd = 
SCOPE_CALL_WITH_INT_RESULT(-1, 
vm_forwardoptions, chan, sender, vmstmp.
curdir, curmsg, 
vmfmts, 
S_OR(context, 
"default"), record_gain, &duration, &vmstmp, urgent_str);
 
 8941                int attach_user_voicemail;
 
 8945                dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0);
 
 8947                    dstvms = create_vm_state_from_user(vmtmp);
 
 8950                    init_mailstream(dstvms, 0);
 
 8951                    if (!dstvms->mailstream) {
 
 8954                        copy_msg_result = 
STORE(vmstmp.
curdir, vmtmp->mailbox, vmtmp->context, curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str, msg_id);
 
 8961                    myserveremail = vmtmp->serveremail;
 
 8964                sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox,
 
 8968                    vmstmp.
fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan,
 
 8969                    NULL, urgent_str, msg_id);
 
 8971                copy_msg_result = 
SCOPE_CALL_WITH_INT_RESULT(-1, 
copy_message, chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str, 
NULL);
 
 8981            if (saved_messages > 0 && !copy_msg_result) {
 
 8998            make_file(msgfile, 
sizeof(msgfile), dir, curmsg);
 
 8999            strcpy(textfile, msgfile);
 
 9000            strcpy(backup, msgfile);
 
 9001            strcpy(backup_textfile, msgfile);
 
 9002            strncat(textfile, 
".txt", 
sizeof(textfile) - strlen(textfile) - 1);
 
 9003            strncat(backup, 
"-bak", 
sizeof(backup) - strlen(backup) - 1);
 
 9004            strncat(backup_textfile, 
"-bak.txt", 
sizeof(backup_textfile) - strlen(backup_textfile) - 1);
 
 9007                rename(backup_textfile, textfile);
 
 9014            make_file(msgfile, 
sizeof(msgfile), dir, curmsg);
 
 9015            strcpy(textfile, msgfile);
 
 9016            strcpy(backup_textfile, msgfile);
 
 9017            strncat(textfile, 
".txt", 
sizeof(textfile) - strlen(textfile) - 1);
 
 9018            strncat(backup_textfile, 
"-bak.txt", 
sizeof(backup_textfile) - strlen(backup_textfile) - 1);
 
 9019            rename(backup_textfile, textfile);
 
 
 9094    if (time_now.tm_year == time_then.tm_year)
 
 9095        snprintf(temp, 
sizeof(temp), 
"%d", time_now.tm_yday);
 
 9097        snprintf(temp, 
sizeof(temp), 
"%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
 
 
 9143    char *callerid, *
name;
 
 9153    if ((cid == 
NULL)||(context == 
NULL))
 
 9157    ast_debug(1, 
"VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
 
 9169                snprintf(prefile, 
sizeof(prefile), 
"%s%s/%s/greet", 
VM_SPOOL_DIR, context, callerid);
 
 9174                        ast_verb(3, 
"Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
 
 9179                        ast_verb(3, 
"Playing envelope info: message from '%s'\n", callerid);
 
 9182                            res = 
wait_file2(chan, vms, 
"vm-from-extension");
 
 9188            ast_debug(1, 
"VM-CID: Numeric caller id: (%s)\n", callerid);
 
 9194                    ast_verb(3, 
"Playing recorded name for CID number '%s' - '%s'\n", callerid,prefile);
 
 9197                    ast_verb(3, 
"Played recorded name result '%d'\n", res);
 
 9200                    wait_file2(chan, vms, 
"vm-from-phonenumber");
 
 9209        ast_debug(1, 
"VM-CID: From an unknown number\n");
 
 9211        res = 
wait_file2(chan, vms, 
"vm-unknown-caller");
 
 
 9222    if (duration == 
NULL)
 
 9226    durations = atoi(duration);
 
 9227    durationm = (durations / 60);
 
 9229    ast_debug(1, 
"VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
 
 9231    if ((!res) && (durationm >= minduration)) {
 
 9236            div_t num = div(durationm, 10);
 
 9238            if (durationm == 1) {
 
 9241            } 
else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
 
 
 9270    const char *origtime, *context, *category, *duration, *
flag;
 
 9285    snprintf(filename, 
sizeof(filename), 
"%s.txt", vms->
fn);
 
 9306                ten = (vms->
curmsg + 1) / 10;
 
 9307                one = (vms->
curmsg + 1) % 10;
 
 9310                    snprintf(nextmsg, 
sizeof(nextmsg), 
"digits/n-%d", vms->
curmsg + 1);
 
 9313                    snprintf(nextmsg, 
sizeof(nextmsg), 
"digits/n-%d", ten * 10);
 
 9317                            snprintf(nextmsg, 
sizeof(nextmsg), 
"digits/n-%d", one);
 
 9359                res = 
wait_file2(chan, vms, 
"vm-meddelandet");  
 
 9426            isprint(res) ? res : 
'?', isprint(res) ? res : 
'?');
 
 
 9433static int imap_remove_file(
char *dir, 
int msgnum)
 
 9441        snprintf(
intro, 
sizeof(
intro), 
"%sintro", fn);
 
 9445    if ((msgnum < 0 && imapgreetings) || msgnum > -1) {
 
 9450        snprintf(full_fn, 
sizeof(full_fn), 
"%s.txt", fn);
 
 9458static int imap_delete_old_greeting (
char *dir, 
struct vm_state *vms)
 
 9460    char *
file, *filename;
 
 9470        ast_log(
AST_LOG_ERROR, 
"Failed to procure file name from directory passed. You should never see this.\n");
 
 9485    for (i = 0; i < vms->mailstream->nmsgs; i++) {
 
 9486        mail_fetchstructure(vms->mailstream, i + 1, &body);
 
 9488        if (body->nested.part->next && body->nested.part->next->body.parameter->value) {
 
 9489            char *attachment = body->nested.part->next->body.parameter->value;
 
 9490            char copy[strlen(attachment) + 1];
 
 9492            strcpy(
copy, attachment); 
 
 9495            filename = 
strsep(&attachment, 
".");
 
 9496            if (!strcmp(filename, file)) {
 
 9497                snprintf(arg, 
sizeof(arg), 
"%d", i + 1);
 
 9498                mail_setflag(vms->mailstream, arg, 
"\\DELETED");
 
 9506    mail_expunge(vms->mailstream);
 
 9508    if (curr_mbox != -1) {
 
 9510        if (init_mailstream(vms, curr_mbox) || !vms->mailstream) {
 
 9519#elif !defined(IMAP_STORAGE) 
 9522    int count_msg, last_msg;
 
 9523    SCOPE_ENTER(3, 
"user: %s dir: %s msg: %d box %d\n",
 
 9538    if (count_msg < 0) {
 
 9563    if (last_msg < -1) {
 
 9565    } 
else if (vms->
lastmsg != last_msg) {
 
 9566        ast_log(
LOG_NOTICE, 
"Resequencing Mailbox: %s, expected %d but found %d message(s) in box with max threshold of %d.\n", vms->
curdir, last_msg + 1, vms->
lastmsg + 1, vmu->
maxmsg);
 
 
 9577    int last_msg_idx = 0;
 
 9580    int res = 0, nummsg;
 
 9587        ast_trace(-1, 
"No messages in mailbox\n");
 
 9600    if (last_msg_idx != vms->
lastmsg) {
 
 9605    for (x = 0; x < last_msg_idx + 1; x++) {
 
 9614            if (strcmp(vms->
fn, fn2)) {
 
 9631                ast_trace(-1, 
"Unable to lock path.  Not moving message to deleted folder.\n");
 
 9650    for (x = vms->
curmsg + 1; x <= nummsg; x++) {
 
 9664        for (x = last_msg_idx - 1; x >= 0; x--) {
 
 
 9705    if (!strcasecmp(box, 
"vm-INBOX") || !strcasecmp(box, 
"vm-Old")){
 
 
 9718    if (!strcasecmp(box, 
"vm-INBOX") || !strcasecmp(box, 
"vm-Old")) {
 
 
 9731    if (!strcasecmp(box, 
"vm-INBOX") || !strcasecmp(box, 
"vm-Old")) {
 
 9732        if (!strcasecmp(box, 
"vm-INBOX"))
 
 
 9747    if (!strcasecmp(box, 
"vm-Family") || !strcasecmp(box, 
"vm-Friends") || !strcasecmp(box, 
"vm-Work")){
 
 
10106                    snprintf(recname, 
sizeof(recname), 
"digits/1kvk");
 
10108                    snprintf(recname, 
sizeof(recname), 
"digits/%dhk", vms->
urgentmessages);
 
10121                    snprintf(recname, 
sizeof(recname), 
"digits/1kvk");
 
10123                    snprintf(recname, 
sizeof(recname), 
"digits/%dhk", vms->
newmessages);
 
10138                    snprintf(recname, 
sizeof(recname), 
"digits/1kvk");
 
10140                    snprintf(recname, 
sizeof(recname), 
"digits/%dhk", vms->
oldmessages);
 
 
10216        } 
else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
 
10217            if (num.rem == 2) {
 
10243        } 
else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
 
10244            if (num.rem == 2) {
 
 
10918            if (skipadvanced) {
 
10933            if (!res && !skipadvanced)
 
10948                int curmsg_deleted;
 
10957                    if (!curmsg_deleted) {
 
 
11007            if (skipadvanced) {
 
11028            if (!res && !skipadvanced)
 
11043                int curmsg_deleted;
 
11051                if (!curmsg_deleted) {
 
 
11122    char newpassword[80] = 
"";
 
11123    char newpassword2[80] = 
"";
 
11125    unsigned char buf[256];
 
11142            cmd = 
play_record_review(chan, 
"vm-rec-name", prefile, 
maxgreet, fmtc, 0, vmu, &duration, 
NULL, 
NULL, record_gain, vms, 
NULL, 
NULL, 0);
 
11143            if (cmd < 0 || cmd == 
't' || cmd == 
'#')
 
11152            cmd = 
play_record_review(chan, 
"vm-rec-unv", prefile, 
maxgreet, fmtc, 0, vmu, &duration, 
NULL, 
NULL, record_gain, vms, 
NULL, 
NULL, 0);
 
11153            if (cmd < 0 || cmd == 
't' || cmd == 
'#')
 
11159            cmd = 
play_record_review(chan, 
"vm-rec-busy", prefile, 
maxgreet, fmtc, 0, vmu, &duration, 
NULL, 
NULL, record_gain, vms, 
NULL, 
NULL, 0);
 
11160            if (cmd < 0 || cmd == 
't' || cmd == 
'#')
 
11170        newpassword[1] = 
'\0';
 
11173            newpassword[0] = 
'\0';
 
11174        if (cmd < 0 || cmd == 
't' || cmd == 
'#')
 
11176        cmd = 
ast_readstring(chan, newpassword + strlen(newpassword), 
sizeof(newpassword) - 1, 2000, 10000, 
"#");
 
11177        if (cmd < 0 || cmd == 
't' || cmd == 
'#')
 
11184            newpassword2[1] = 
'\0';
 
11187                newpassword2[0] = 
'\0';
 
11188            if (cmd < 0 || cmd == 
't' || cmd == 
'#')
 
11190            cmd = 
ast_readstring(chan, newpassword2 + strlen(newpassword2), 
sizeof(newpassword2) - 1, 2000, 10000, 
"#");
 
11191            if (cmd < 0 || cmd == 
't' || cmd == 
'#')
 
11193            if (!strcmp(newpassword, newpassword2))
 
11209    ast_debug(1, 
"User %s set password to %s of length %d\n", vms->
username, newpassword, (
int) strlen(newpassword));
 
 
11220    char newpassword[80] = 
"";
 
11221    char newpassword2[80] = 
"";
 
11223    unsigned char buf[256];
 
11236    while ((cmd >= 0) && (cmd != 
't')) {
 
11242            cmd = 
SCOPE_CALL_WITH_INT_RESULT(-1, 
play_record_review, chan, 
"vm-rec-unv", prefile, 
maxgreet, fmtc, 0, vmu, &duration, 
NULL, 
NULL, record_gain, vms, 
NULL, 
NULL, 0);
 
11246            cmd = 
SCOPE_CALL_WITH_INT_RESULT(-1, 
play_record_review, chan, 
"vm-rec-busy", prefile, 
maxgreet, fmtc, 0, vmu, &duration, 
NULL, 
NULL, record_gain, vms, 
NULL, 
NULL, 0);
 
11250            cmd = 
SCOPE_CALL_WITH_INT_RESULT(-1, 
play_record_review, chan, 
"vm-rec-name", prefile, 
maxgreet, fmtc, 0, vmu, &duration, 
NULL, 
NULL, record_gain, vms, 
NULL, 
NULL, 0);
 
11260            newpassword[1] = 
'\0';
 
11263                newpassword[0] = 
'\0';
 
11267                if ((cmd = 
ast_readstring(chan, newpassword + strlen(newpassword), 
sizeof(newpassword) - 1, 2000, 10000, 
"#")) < 0) {
 
11280            newpassword2[1] = 
'\0';
 
11283                newpassword2[0] = 
'\0';
 
11288                if ((cmd = 
ast_readstring(chan, newpassword2 + strlen(newpassword2), 
sizeof(newpassword2) - 1, 2000, 10000, 
"#")) < 0) {
 
11292            if (strcmp(newpassword, newpassword2)) {
 
11308            ast_debug(1, 
"User %s set password to %s of length %d\n",
 
11309                vms->
username, newpassword, (
int) strlen(newpassword));
 
11336                isprint(cmd) ? cmd : 
'?', isprint(cmd) ? cmd : 
'?');
 
 
11366    unsigned char buf[256];
 
11380    while ((cmd >= 0) && (cmd != 
't')) {
 
11385            cmd = 
play_record_review(chan, 
"vm-rec-temp", prefile, 
maxgreet, fmtc, 0, vmu, &duration, 
NULL, 
NULL, record_gain, vms, 
NULL, 
NULL, 0);
 
11393                cmd = 
play_record_review(chan, 
"vm-rec-temp", prefile, 
maxgreet, fmtc, 0, vmu, &duration, 
NULL, 
NULL, record_gain, vms, 
NULL, 
NULL, 0);
 
11396                DELETE(prefile, -1, prefile, vmu);
 
11406                        "vm-tempgreeting2" : 
"vm-tempgreeting");
 
11417                    isprint(cmd) ? cmd : 
'?', isprint(cmd) ? cmd : 
'?');
 
 
11443        if (!strcasecmp(vms->
vmbox, 
"vm-INBOX") ||!strcasecmp(vms->
vmbox, 
"vm-Old")){
 
11445                snprintf(vms->
fn, 
sizeof(vms->
fn), 
"vm-%ss", vms->
curbox);
 
11454                snprintf(vms->
fn, 
sizeof(vms->
fn), 
"vm-%s", vms->
curbox);
 
 
11470        if (!strcasecmp(vms->
fn, 
"INBOX")) {
 
 
11498            snprintf(vms->
fn, 
sizeof(vms->
fn), 
"vm-%s", vms->
curbox);
 
 
11526            snprintf(vms->
fn, 
sizeof(vms->
fn), 
"vm-%s", vms->
curbox);
 
 
11548        snprintf(vms->
fn, 
sizeof(vms->
fn), 
"vm-%s", vms->
curbox);
 
 
11579            snprintf(vms->
fn, 
sizeof(vms->
fn), 
"vm-%s", vms->
curbox);
 
 
11603            snprintf(vms->
fn, 
sizeof(vms->
fn), 
"vm-%s", vms->
curbox);
 
 
11633            snprintf(vms->
fn, 
sizeof(vms->
fn), 
"vm-%s", vms->
curbox);
 
 
11657            snprintf(vms->
fn, 
sizeof(vms->
fn), 
"vm-%s", vms->
curbox);
 
 
11700            int skipuser, 
int max_logins, 
int silent)
 
11702    int useadsi = 0, valid = 0, logretries = 0;
 
11708    if (!skipuser && useadsi)
 
11717    while (!valid && (logretries < max_logins)) {
 
11727                ast_verb(3, 
"Username not entered\n");
 
11730        } 
else if (
mailbox[0] == 
'*') {
 
11732            ast_verb(4, 
"Mailbox begins with '*', attempting jump to extension 'a'\n");
 
11737            ast_verb(4, 
"Jump to extension 'a' failed; setting mailbox to NULL\n");
 
11745            char fullusername[80];
 
11748            strncat(fullusername, 
mailbox, 
sizeof(fullusername) - 1 - strlen(fullusername));
 
11753        memset(&vmus, 0, 
sizeof(vmus));
 
11772                ast_verb(4, 
"Password begins with '*', attempting jump to extension 'a'\n");
 
11779                ast_verb(4, 
"Jump to extension 'a' failed; setting mailbox and user to NULL\n");
 
11789            if (passptr[0] == 
'-') passptr++;
 
11791        if (vmu && !strcmp(passptr, 
password))
 
11800            if (skipuser || logretries >= max_logins) {
 
11821    if (!valid && (logretries >= max_logins)) {
 
11827    if (vmu && !skipuser) {
 
 
11836    const char *msg_id)
 
 
11885    memset(&vmus, 0, 
sizeof(vmus));
 
11886    memset(&vms, 0, 
sizeof(vms));
 
11889        goto play_msg_cleanup;
 
11901            goto play_msg_cleanup;
 
11913            goto play_msg_cleanup;
 
11929        vmstate_delete(&vms);
 
 
11979#define VMBOX_STRING_HEADER_FORMAT "%-32.32s %-32.32s %-16.16s %-16.16s %-16.16s %-16.16s\n" 
11980#define VMBOX_STRING_DATA_FORMAT   "%-32.32s %-32.32s %-16.16s %-16.16s %-16.16s %-16.16s\n" 
11986    memset(&vmus, 0, 
sizeof(vmus));
 
11987    memset(&vms, 0, 
sizeof(vms));
 
 
12002#define VM_STRING_HEADER_FORMAT "%-8.8s %-32.32s %-32.32s %-9.9s %-6.6s %-30.30s\n" 
12011    if (!mailbox_snapshot) {
 
12012        ast_cli(
a->fd, 
"Can't create snapshot for voicemail user %s@%s\n", mailbox, context);
 
12018    for (i = 0; i < mailbox_snapshot->
folders; i++) {
 
12021                    msg->flag, 
msg->msg_id);
 
 
12043    const char *from_mailbox = 
a->argv[2];
 
12044    const char *from_context = 
a->argv[3];
 
12045    const char *from_folder = 
a->argv[4];
 
12046    const char *
id[] = { 
a->argv[5] };
 
12047    const char *to_mailbox = 
a->argv[6];
 
12048    const char *to_context = 
a->argv[7];
 
12049    const char *to_folder = 
a->argv[8];
 
12050    int ret = 
vm_msg_forward(from_mailbox, from_context, from_folder, to_mailbox, to_context, to_folder, 1, 
id, 0);
 
12052        ast_cli(
a->fd, 
"Error forwarding message %s from mailbox %s@%s %s to mailbox %s@%s %s\n",
 
12053                    id[0], from_mailbox, from_context, from_folder, to_mailbox, to_context, to_folder);
 
12055        ast_cli(
a->fd, 
"Forwarded message %s from mailbox %s@%s %s to mailbox %s@%s %s\n",
 
12056                    id[0], from_mailbox, from_context, from_folder, to_mailbox, to_context, to_folder);
 
 
12063    const char *mailbox = 
a->argv[2];
 
12064    const char *context = 
a->argv[3];
 
12065    const char *from_folder = 
a->argv[4];
 
12066    const char *
id[] = { 
a->argv[5] };
 
12067    const char *to_folder = 
a->argv[6];
 
12068    int ret =  
vm_msg_move(mailbox, context, 1, from_folder, 
id, to_folder);
 
12070        ast_cli(
a->fd, 
"Error moving message %s from mailbox %s@%s %s to %s\n",
 
12071                    id[0], mailbox, context, from_folder, to_folder);
 
12073        ast_cli(
a->fd, 
"Moved message %s from mailbox %s@%s %s to %s\n",
 
12074                    id[0], mailbox, context, from_folder, to_folder);
 
 
12081    const char *mailbox = 
a->argv[2];
 
12082    const char *context = 
a->argv[3];
 
12083    const char *folder = 
a->argv[4];
 
12084    const char *
id[] = { 
a->argv[5] };
 
12087        ast_cli(
a->fd, 
"Error removing message %s from mailbox %s@%s %s\n",
 
12088                    id[0], mailbox, context, folder);
 
12090        ast_cli(
a->fd, 
"Removed message %s from mailbox %s@%s %s\n",
 
12091                    id[0], mailbox, context, folder);
 
 
12098    const char *
word = 
a->word;
 
12109        wordlen = strlen(
word);
 
12112            if (!strncasecmp(
word, vmu->
mailbox , wordlen)) {
 
12122    } 
else if (pos == 4) {
 
12124        const char *box = 
a->argv[3];
 
12125        wordlen = strlen(
word);
 
 
12147        e->
command = 
"voicemail show mailbox";
 
12149        "Usage: voicemail show mailbox <mailbox> <context>\n" 
12150        "       Show contents of mailbox <mailbox>@<context>\n";
 
12158    if (
a->argc != 5) {
 
 
12188    const char *
word = 
a->word;
 
12194    const char *
context = 
"", *
mailbox = 
"", *folder = 
"", *
id = 
"";
 
12197    if (pos > maxpos) {
 
12203    if (pos == 2 || (pos == 6 && maxpos == 8)) {
 
12205        wordlen = strlen(
word);
 
12208            if (!strncasecmp(
word, vmu->
mailbox , wordlen)) {
 
12218    } 
else if (pos == 3 || pos == 7) {
 
12220        mailbox = (pos == 3) ? 
a->argv[2] : 
a->argv[6];
 
12221        wordlen = strlen(
word);
 
12234    } 
else if (pos == 4 || pos == 8 || (pos == 6 && maxpos == 6) ) {
 
12237        wordlen = strlen(
word);
 
12244    } 
else if (pos == 5) {
 
12248        mailbox = 
a->argv[2];
 
12249        context = 
a->argv[3];
 
12250        folder = 
a->argv[4];
 
12251        wordlen = strlen(
word);
 
12263                if (
id && !strncasecmp(
word, 
msg->msg_id, wordlen) && ++which > 
state) {
 
 
12281        e->
command = 
"voicemail forward";
 
12283        "Usage: voicemail forward <from_mailbox> <from_context> <from_folder> <messageid> <to_mailbox> <to_context> <to_folder>\n" 
12284        "       Forward message <messageid> in mailbox <mailbox>@<context> <from_folder>\n" 
12285        "       to mailbox <mailbox>@<context> <to_folder>\n";
 
12293    if (
a->argc != 9) {
 
 
12308        e->
command = 
"voicemail move";
 
12310        "Usage: voicemail move <mailbox> <context> <from_folder> <messageid> <to_folder>\n" 
12311        "       Move message <messageid> in mailbox <mailbox>&<context> from <from_folder> to <to_folder>\n";
 
12319    if (
a->argc != 7) {
 
 
12334        e->
command = 
"voicemail remove";
 
12336        "Usage: voicemail remove <mailbox> <context> <from_folder> <messageid>\n" 
12337        "       Remove message <messageid> from <from_folder> in mailbox <mailbox>@<context>\n";
 
12345    if (
a->argc != 6) {
 
 
12364    char prefixstr[80] =
"";
 
12365    char ext_context[256]=
"";
 
12372    int silentexit = 0;
 
12374    signed char record_gain = 0;
 
12376    int play_folder = 0;
 
12405        if (
args.argc == 2) {
 
12415                        record_gain = (
signed char) gain;
 
12435                if (play_folder > 9 || play_folder < 0) {
 
12437                        "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n",
 
12447            while (*(
args.argv0)) {
 
12448                if (*(
args.argv0) == 
's')
 
12450                else if (*(
args.argv0) == 
'p')
 
12461        if ((context = strchr(
args.argv0, 
'@')))
 
12515    pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
 
12516    pthread_setspecific(ts_vmstate.key, &vms);
 
12518    vms.interactive = 1;
 
12522    vmstate_insert(&vms);
 
12523    init_vm_state(&vms);
 
12529        ast_channel_language_set(chan, vmu->
language);
 
12534    ast_trace(-1, 
"Before open_mailbox\n");
 
12537        ast_trace(-1, 
"open mailbox: %d\n", res);
 
12545        ast_trace(-1, 
"open mailbox: %d\n", res);
 
12554        ast_trace(-1, 
"open mailbox: %d\n", res);
 
12571            ast_trace(-1, 
"open mailbox: %d\n", res);
 
12609        if ((cmd == 
't') || (cmd == 
'#')) {
 
12615        } 
else if (cmd < 0) {
 
12624        ast_debug(3, 
"Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit);
 
12625        if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
 
12626            ast_debug(1, 
"*** QUOTA EXCEEDED!!\n");
 
12643        isprint(cmd) ? cmd : 
'?', isprint(cmd) ? cmd : 
'?');
 
12647    while ((cmd > -1) && (cmd != 
't') && (cmd != 
'#')) {
 
12649        ast_trace(-1, 
"Main menu: %d %c\n", cmd, (cmd >= 32 && cmd <= 126 ? cmd : 
' '));
 
12665                isprint(cmd) ? cmd : 
'?', isprint(cmd) ? cmd : 
'?');
 
12668            } 
else if (cmd > 0) {
 
12672                    ast_trace(-1, 
"close mailbox: %d\n", res);
 
12676                if (cmd != 11) in_urgent = 0;
 
12679                    ast_trace(-1, 
"open mailbox: %d\n", res);
 
12699            while ((cmd > -1) && (cmd != 
't') && (cmd != 
'#')) {
 
12706                            ast_trace(-1, 
"advanced options: %d\n", cmd);
 
12716                        ast_verb(3, 
"Callback Requested\n");
 
12719                        ast_trace(-1, 
"advanced options: %d\n", cmd);
 
12737                            ast_trace(-1, 
"advanced options: %d\n", cmd);
 
12764                            ast_trace(-1, 
"forward message: %d\n", cmd);
 
12807                        isprint(cmd) ? cmd : 
'?', isprint(cmd) ? cmd : 
'?');
 
12830                        ast_trace(-1, 
"close mailbox: %d\n", res);
 
12835                        ast_trace(-1, 
"open mailbox: %d\n", res);
 
12838                    ast_debug(1, 
"No more new messages, opened INBOX and got %d Urgent messages\n", vms.
lastmsg + 1);
 
12865                        ast_trace(-1, 
"close mailbox: %d\n", res);
 
12870                        ast_trace(-1, 
"open mailbox: %d\n", res);
 
12873                    ast_debug(1, 
"No more urgent messages, opened INBOX and got %d new messages\n", vms.
lastmsg + 1);
 
12892                    if (play_folder == 0) {
 
12899                    else if (play_folder == 1)
 
12903                    if (play_folder == 0) {
 
12910                    else if (play_folder == 1)
 
12926                        if (in_urgent == 1) {
 
12931                                ast_trace(-1, 
"close mailbox: %d\n", res);
 
12936                                ast_trace(-1, 
"open mailbox: %d\n", res);
 
12939                            ast_debug(1, 
"No more urgent messages, opened INBOX and got %d new messages\n", vms.
lastmsg + 1);
 
12961                    ast_trace(-1, 
"forward message: %d\n", res);
 
12974                        ast_trace(-1, 
"close mailbox: %d\n", res);
 
12979                        ast_trace(-1, 
"open mailbox: %d\n", res);
 
12982                    ast_debug(1, 
"No more urgent messages, opened INBOX and got %d new messages\n", vms.
lastmsg + 1);
 
13003                isprint(cmd) ? cmd : 
'?', isprint(cmd) ? cmd : 
'?');
 
13008            } 
else if (cmd > 0) {
 
13009                box = cmd = cmd - 
'0';
 
13013                    ast_trace(-1, 
"save to folder: %d\n", res);
 
13015#ifndef IMAP_STORAGE 
13027            snprintf(vms.
fn, 
sizeof(vms.
fn), 
"vm-%s", 
mbox(vmu, box));
 
13056                            ast_trace(-1, 
"close mailbox: %d\n", res);
 
13061                            ast_trace(-1, 
"open mailbox: %d\n", res);
 
13064                        ast_debug(1, 
"No more urgent messages, opened INBOX and got %d new messages\n", vms.
lastmsg + 1);
 
13113                ast_trace(-1, 
"open mailbox: %d\n", res);
 
13124    if ((cmd == 
't') || (cmd == 
'#')) {
 
13152        int new = 0, old = 0, urgent = 0;
 
13153        snprintf(ext_context, 
sizeof(ext_context), 
"%s@%s", vms.
username, vmu->
context);
 
13161    ast_debug(3, 
"*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup);
 
13162    if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != 
NULL) {
 
13164#ifdef HAVE_IMAP_TK2006 
13165        if (LEVELUIDPLUS (vms.mailstream)) {
 
13166            mail_expunge_full(vms.mailstream, NIL, EX_UID);
 
13169            mail_expunge(vms.mailstream);
 
13175        vmstate_delete(&vms);
 
13182    pthread_setspecific(ts_vmstate.key, 
NULL);
 
 
13200    memset(&leave_options, 0, 
sizeof(leave_options));
 
13205        if (
args.argc == 2) {
 
13231        res = 
ast_app_getdata(chan, 
"vm-whichbox", temp, 
sizeof(temp) - 1, 0);
 
 
13281        ast_log(
LOG_ERROR, 
"Voicemail data file %s/%d.txt has no [message] category?\n", dir, msg);
 
 
13302        ast_log(
LOG_WARNING, 
"Mailbox %s in context %s begins with '*' character.  The '*' character," 
13303                "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 
13304                "\n\tpredefined extension 'a'.  A mailbox or password beginning with '*' is not valid" 
13305                "\n\tand will be ignored.\n", box, 
context);
 
13312                ast_log(
LOG_WARNING, 
"\nIt has been detected that you have defined mailbox '%s' in separate\ 
13313                        \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 
13314                        \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 
13315                        \n\tamend your voicemail.conf file to avoid this situation.\n", box);
 
 
13345    int new = 0, old = 0, urgent = 0;
 
13356    if ((s = 
strsep(&stringp, 
","))) {
 
13359                "\n\tmust be reset in voicemail.conf.\n", box);
 
13364    if (stringp && (s = 
strsep(&stringp, 
","))) {
 
13367    if (stringp && (s = 
strsep(&stringp, 
","))) {
 
13370    if (stringp && (s = 
strsep(&stringp, 
","))) {
 
13390    imap_logout(mailbox_full);
 
 
13397#ifdef TEST_FRAMEWORK 
13403    static const char options_string[] = 
"attach=yes|attachfmt=wav49|" 
13404        "serveremail=someguy@digium.com|fromstring=Voicemail System|tz=central|delete=yes|saycid=yes|" 
13405        "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|leaveurgent=yes|" 
13406        "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 
13407        "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 
13408        "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 
13409        "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 
13410        "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 
13411        "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}";
 
13413    static const char option_string2[] = 
"imapuser=imapuser|imappassword=imappasswd|" 
13414        "imapfolder=INBOX|imapvmshareid=6000|imapserver=imapserver|imapport=1234|imapflags=flagged";
 
13419        info->name = 
"vmuser";
 
13420        info->category = 
"/apps/app_voicemail/";
 
13421        info->summary = 
"Vmuser unit test";
 
13422        info->description =
 
13423            "This tests passing all supported parameters to apply_options, the voicemail user config parser";
 
13441    if (strcasecmp(vmu->
attachfmt, 
"wav49")) {
 
13445    if (strcasecmp(vmu->
fromstring, 
"Voicemail System")) {
 
13449    if (strcasecmp(vmu->
serveremail, 
"someguy@digium.com")) {
 
13453    if (!vmu->
emailsubject || strcasecmp(vmu->
emailsubject, 
"[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) {
 
13457    if (!vmu->
emailbody || strcasecmp(vmu->
emailbody, 
"Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) {
 
13461    if (strcasecmp(vmu->
zonetag, 
"central")) {
 
13521    if (strcasecmp(vmu->
callback, 
"somecontext")) {
 
13525    if (strcasecmp(vmu->
dialout, 
"somecontext2")) {
 
13529    if (strcasecmp(vmu->
exit, 
"somecontext3")) {
 
13560    if (strcasecmp(vmu->imapuser, 
"imapuser")) {
 
13564    if (strcasecmp(vmu->imappassword, 
"imappasswd")) {
 
13568    if (strcasecmp(vmu->imapfolder, 
"INBOX")) {
 
13572    if (strcasecmp(vmu->imapvmshareid, 
"6000")) {
 
13576    if (strcasecmp(vmu->imapserver, 
"imapserver")) {
 
13580    if (strcasecmp(vmu->imapport, 
"1234")) {
 
13584    if (strcasecmp(vmu->imapflags, 
"flagged")) {
 
13614        ast_log(
LOG_ERROR, 
"VM_INFO requires an argument (<mailbox>[@<context>],attribute[,folder])\n");
 
13624        ast_log(
LOG_ERROR, 
"VM_INFO requires an argument (<mailbox>[@<context>],attribute[,folder])\n");
 
13628    memset(&svm, 0, 
sizeof(svm));
 
13631    if (!strncasecmp(arg.attribute, 
"exists", 5)) {
 
13638        if (!strncasecmp(arg.attribute, 
"password", 8)) {
 
13640        } 
else if (!strncasecmp(arg.attribute, 
"fullname", 8)) {
 
13642        } 
else if (!strncasecmp(arg.attribute, 
"email", 5)) {
 
13644        } 
else if (!strncasecmp(arg.attribute, 
"pager", 5)) {
 
13646        } 
else if (!strncasecmp(arg.attribute, 
"language", 8)) {
 
13648        } 
else if (!strncasecmp(arg.attribute, 
"locale", 6)) {
 
13650        } 
else if (!strncasecmp(arg.attribute, 
"tz", 2)) {
 
13652        } 
else if (!strncasecmp(arg.attribute, 
"count", 5)) {
 
13661                ast_log(
LOG_ERROR, 
"Unable to retrieve message count for mailbox %s\n", arg.mailbox_context);
 
13665            snprintf(
buf, 
len, 
"%d", res);
 
13667            ast_log(
LOG_ERROR, 
"Unknown attribute '%s' for VM_INFO\n", arg.attribute);
 
 
13687    int silent = 0, skipuser = 0;
 
13713    } 
else if (
mailbox[0] == 
'*') {
 
 
13726    const char *cat = 
NULL;
 
13735        "=============================================================\n" 
13736        "=== Configured Voicemail Users ==============================\n" 
13737        "=============================================================\n" 
13743            "=== Mailbox ...\n" 
13749            "=== ---------------------------------------------------------\n" 
13754        "=============================================================\n" 
 
13773    wordlen = strlen(
word);
 
 
13794#define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 
13796    int users_counter = 0;
 
13800        e->
command = 
"voicemail show users [for]";
 
13802            "Usage: voicemail show users [for <context>]\n" 
13803            "       Lists all mailboxes currently set up\n";
 
13809    if ((
a->argc < 3) || (
a->argc > 5) || (
a->argc == 4))
 
13811    if (
a->argc == 5) {
 
13812        if (strcmp(
a->argv[3],
"for"))
 
13819            ast_cli(
a->fd, 
"You must specify a specific context to show users from realtime!\n");
 
13827        ast_cli(
a->fd, 
"There are no voicemail users currently defined\n");
 
13850        int newmsgs = 0, oldmsgs = 0;
 
13851        char count[12], tmp[256] = 
"";
 
13856            snprintf(count, 
sizeof(count), 
"%d", newmsgs);
 
13862    ast_cli(
a->fd, 
"%d voicemail users configured.\n", users_counter);
 
 
13870#define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 
13875        e->
command = 
"voicemail show zones";
 
13877            "Usage: voicemail show zones\n" 
13878            "       Lists zone message formats\n";
 
13894        ast_cli(
a->fd, 
"There are no voicemail zones currently defined\n");
 
 
13907#define ALIASES_OUTPUT_FORMAT "%-32s %-32s\n" 
13912        e->
command = 
"voicemail show aliases";
 
13914            "Usage: voicemail show aliases\n" 
13915            "       Lists mailbox aliases\n";
 
13925        ast_cli(
a->fd, 
"Aliases are not enabled\n");
 
 
13947        e->
command = 
"voicemail reload";
 
13949            "Usage: voicemail reload\n" 
13950            "       Reload voicemail configuration\n";
 
13959    ast_cli(
a->fd, 
"Reloading voicemail configuration...\n");
 
 
13978    int new = 0, old = 0, urgent = 0;
 
13988    if (imap_poll_logout) {
 
 
14004        struct timespec ts = { 0, };
 
14005        struct timeval wait;
 
14014        ts.tv_sec = wait.tv_sec;
 
14015        ts.tv_nsec = wait.tv_usec * 1000;
 
 
14026static void imap_logout(
const char *mailbox_id)
 
14039    memset(&vmus, 0, 
sizeof(vmus));
 
14041    if (!(vmu = 
find_user(&vmus, 
context, mailbox)) || vmu->imapuser[0] == 
'\0') {
 
14045    vms = get_vm_state_by_imapuser(vmu->imapuser, 0);
 
14047        vms = get_vm_state_by_mailbox(mailbox, 
context, 0);
 
14054    vms->mailstream = mail_close(vms->mailstream);
 
14057    vmstate_delete(vms);
 
14060static int imap_close_subscribed_mailbox(
struct ast_mwi_state *mwi_state, 
void *data)
 
14083    imap_close_subscribed_mailbox(mwi_state, 
NULL);
 
 
14157        const char* event_name,
 
14158        const char* actionid
 
14166    if((s == 
NULL) || (vmu == 
NULL) || (event_name == 
NULL) || (actionid == 
NULL)) {
 
14186        ast_log(
LOG_ERROR, 
"Could not get mailbox count. user[%s], context[%s]\n",
 
14194        "VMContext: %s\r\n" 
14195        "VoiceMailbox: %s\r\n" 
14199        "ServerEmail: %s\r\n" 
14200        "FromString: %s\r\n" 
14201        "MailCommand: %s\r\n" 
14207        "ExitContext: %s\r\n" 
14208        "SayDurationMinimum: %d\r\n" 
14209        "SayEnvelope: %s\r\n" 
14211        "AttachMessage: %s\r\n" 
14212        "AttachmentFormat: %s\r\n" 
14213        "DeleteMessage: %s\r\n" 
14214        "VolumeGain: %.2f\r\n" 
14215        "CanReview: %s\r\n" 
14216        "CanMarkUrgent: %s\r\n" 
14217        "CallOperator: %s\r\n" 
14218        "MaxMessageCount: %d\r\n" 
14219        "MaxMessageLength: %d\r\n" 
14220        "NewMessageCount: %d\r\n" 
14221        "OldMessageCount: %d\r\n" 
14224        "IMAPServer: %s\r\n" 
14226        "IMAPFlags: %s\r\n" 
 
14282        const char* event_name,
 
14283        const char* actionid)
 
14287    int nummessages = 0;
 
14292    if (!mailbox_snapshot) {
 
14300    for (i = 0; i < mailbox_snapshot->
folders; i++) {
 
 
14345             (at = strchr(mwi_state->
uniqueid, 
'@')) &&
 
14349             (at = strchr(mwi_state->
uniqueid, 
'@')) &&
 
14350             strcmp(context, at + 1) == 0) ||
 
14353             (at = strchr(mwi_state->
uniqueid, 
'@')) &&
 
14355             strcmp(context, at + 1) == 0)
 
 
14375    char actionid[128];
 
14387    actionid[0] = 
'\0';
 
14389        snprintf(actionid, 
sizeof(actionid), 
"ActionID: %s\r\n", 
id);
 
14393    memset(&svm, 0, 
sizeof(svm));
 
14397        astman_send_ack(s, m, 
"There is no voicemail user of the given info.");
 
 
14421    char actionid[128];
 
14425    actionid[0] = 
'\0';
 
14427        snprintf(actionid, 
sizeof(actionid), 
"ActionID: %s\r\n", 
id);
 
14433        astman_send_ack(s, m, 
"There are no voicemail users currently defined.");
 
 
14462    char actionid[128];
 
14473    actionid[0] = 
'\0';
 
14475        snprintf(actionid, 
sizeof(actionid), 
"ActionID: %s\r\n", 
id);
 
14479    memset(&svm, 0, 
sizeof(svm));
 
14483        astman_send_ack(s, m, 
"There is no voicemail user matching the given user.");
 
 
14606    if (
vm_msg_forward(from_mailbox, from_context, from_folder, to_mailbox, to_context, to_folder, 1, 
id, 0)) {
 
 
14663                if (!
str->used || 
str->str[
str->used - 1] != 
'\r') {
 
 
14718#ifdef TEST_FRAMEWORK 
14730    size_t from_len = strlen(
alias) + 1;
 
14731    size_t to_len = strlen(
mailbox) + 1;
 
14733    mapping = 
ao2_alloc(
sizeof(*mapping) + from_len + to_len, 
NULL);
 
 
14773            char storage[strlen(
var->value) + 1];
 
14780            strcpy(storage, 
var->value); 
 
 
14805        if (strcasecmp(cat, 
"general") == 0
 
14807            || strcasecmp(cat, 
"zonemessages") == 0) {
 
 
14822    char *q, *stringp, *tmp;
 
14824    unsigned int tmpadsi[4];
 
14825    long tps_queue_low;
 
14826    long tps_queue_high;
 
14878        strcpy(odbc_database, 
"asterisk");
 
14883        strcpy(odbc_table, 
"voicemessages");
 
14887        odbc_table_len = strlen(odbc_table);
 
14923            if (sscanf(
val, 
"%30d", &x) == 1)
 
14992                expungeonhangup = 0;
 
14994                expungeonhangup = 1;
 
14996            expungeonhangup = 1;
 
15023            imap_poll_logout = 0;
 
15031            mail_parameters(NIL, SET_READTIMEOUT, (
void *) (atol(
val)));
 
15033            mail_parameters(NIL, SET_READTIMEOUT, (
void *) 60L);
 
15037            mail_parameters(NIL, SET_WRITETIMEOUT, (
void *) (atol(
val)));
 
15039            mail_parameters(NIL, SET_WRITETIMEOUT, (
void *) 60L);
 
15043            mail_parameters(NIL, SET_OPENTIMEOUT, (
void *) (atol(
val)));
 
15045            mail_parameters(NIL, SET_OPENTIMEOUT, (
void *) 60L);
 
15049            mail_parameters(NIL, SET_CLOSETIMEOUT, (
void *) (atol(
val)));
 
15051            mail_parameters(NIL, SET_CLOSETIMEOUT, (
void *) 60L);
 
15067            ast_debug(1, 
"Enabled SMDI voicemail notification\n");
 
15071                ast_debug(1, 
"No SMDI interface set, trying default (/dev/ttyS0)\n");
 
15075                ast_log(
AST_LOG_ERROR, 
"No valid SMDI interface specified, disabling SMDI voicemail notification\n");
 
15090            if (sscanf(
val, 
"%30d", &x) == 1) {
 
15099            if (sscanf(
val, 
"%30d", &x) == 1) {
 
15116                ast_log(
LOG_ERROR, 
"Error processing format string, defaulting to format 'wav'\n");
 
15124            if (sscanf(
val, 
"%30d", &x) == 1) {
 
15132            if (sscanf(
val, 
"%30d", &x) == 1) {
 
15141            if (sscanf(
val, 
"%30d", &x) == 1) {
 
15150            if (sscanf(
val, 
"%30d", &x) == 1) {
 
15168            ast_debug(1, 
"VM_CID Internal context string: %s\n", 
val);
 
15172                    q = 
strsep(&stringp, 
",");
 
15173                    while ((*q == 
' ')||(*q == 
'\t')) 
 
15183            ast_debug(1, 
"VM Review Option disabled globally\n");
 
15191            ast_debug(1, 
"VM leave urgent messages disabled globally\n");
 
15198            ast_debug(1, 
"VM Temporary Greeting Reminder Option disabled globally\n");
 
15201            ast_debug(1, 
"VM Temporary Greeting Reminder Option enabled globally\n");
 
15205            ast_debug(1, 
"VM next message wrap disabled globally\n");
 
15211            ast_debug(1, 
"VM Operator break disabled globally\n");
 
15217            ast_debug(1, 
"VM CID Info before msg disabled globally\n");
 
15223            ast_debug(1, 
"Send Voicemail msg disabled globally\n");
 
15229            ast_debug(1, 
"ENVELOPE before msg enabled globally\n");
 
15235            ast_debug(1, 
"Move Heard enabled globally\n");
 
15241            ast_debug(1, 
"Autoset of Urgent flag on forwarded Urgent messages disabled globally\n");
 
15247            ast_debug(1, 
"Duration info before msg enabled globally\n");
 
15254            if (sscanf(
val, 
"%30d", &x) == 1) {
 
15262            ast_debug(1, 
"We are not going to skip to the next msg after save/delete\n");
 
15328            val = 
"voicemail.conf";
 
15330        if (!(strcmp(
val, 
"spooldir"))) {
 
15350        strcpy(
charset, 
"ISO-8859-1");
 
15376            sscanf(
val, 
"%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
 
15377            for (x = 0; x < 4; x++) {
 
15378                memcpy(&
adsifdn[x], &tmpadsi[x], 1);
 
15382            sscanf(
val, 
"%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
 
15383            for (x = 0; x < 4; x++) {
 
15384                memcpy(&
adsisec[x], &tmpadsi[x], 1);
 
15413            if (sscanf(
val, 
"%30ld", &tps_queue_high) != 1 || tps_queue_high <= 0) {
 
15418        tps_queue_low = -1;
 
15420            if (sscanf(
val, 
"%30ld", &tps_queue_low) != 1 ||
 
15421                tps_queue_low < -1 || tps_queue_high < tps_queue_low) {
 
15423                tps_queue_low = -1;
 
 
15461    snprintf(dir, 
sizeof(dir), 
"%s%s/%s/greet", 
VM_SPOOL_DIR, context, mailbox);
 
15462    ast_debug(2, 
"About to try retrieving name file %s\n", dir);
 
15463    RETRIEVE(dir, -1, mailbox, context);
 
 
15491    return sayname(chan, mailbox, context);
 
 
15508    ast_log(
LOG_NOTICE, 
"Failed reading voicemail password from %s, using secret from config file\n", secretfn);
 
 
15556    if ((res = 
sayname(chan, mailbox, context)) < 0) {
 
15557        ast_debug(3, 
"Greeting not found for '%s@%s', falling back to mailbox number.\n", mailbox, context);
 
 
15567#ifdef TEST_FRAMEWORK 
15582    static const char TEST_CONTEXT[] = 
"very_long_unique_context_so_that_nobody_will_ever_have_the_same_one_configured_3141592653";
 
15590        .
write = fake_write,
 
15596        info->name = 
"vmsayname_exec";
 
15597        info->category = 
"/apps/app_voicemail/";
 
15598        info->summary = 
"Vmsayname unit test";
 
15599        info->description =
 
15600            "This tests passing various parameters to vmsayname";
 
15607        NULL, 
NULL, 0, 0, 
"TestChannel1"))) {
 
15608        goto exit_vmsayname_test;
 
15614        goto exit_vmsayname_test;
 
15634            goto exit_vmsayname_test;
 
15639                goto exit_vmsayname_test;
 
15644            if ((res = symlink(dir, dir2))) {
 
15646                goto exit_vmsayname_test;
 
15661exit_vmsayname_test:
 
15684    struct test_files *tmp = 
ast_alloca(
sizeof(
struct test_files) * 3);
 
15686    const char origweasels[] = 
"tt-weasels";
 
15687    const char testcontext[] = 
"test";
 
15688    const char testmailbox[] = 
"00000000";
 
15689    const char testspec[] = 
"00000000@test";
 
15691    int new, old, urgent;
 
15692    const char *folders[3] = { 
"Old", 
"Urgent", 
"INBOX" };
 
15693    const int folder2mbox[3] = { 1, 11, 0 };
 
15694    const int expected_results[3][12] = {
 
15696        {          1,            0,         0,      1,         0,      0,       1,          0,       0,      1,         0,      0 },
 
15697        {          1,            1,         1,      1,         0,      1,       1,          1,       0,      1,         1,      1 },
 
15698        {          1,            1,         1,      1,         0,      2,       1,          1,       1,      1,         1,      2 },
 
15703        info->name = 
"test_voicemail_msgcount";
 
15704        info->category = 
"/apps/app_voicemail/";
 
15705        info->summary = 
"Test Voicemail status checks";
 
15706        info->description =
 
15707            "Verify that message counts are correct when retrieved through the public API";
 
15714    snprintf(syscmd, 
sizeof(syscmd), 
"rm -rf \"%s%s/%s\"", 
VM_SPOOL_DIR, testcontext, testmailbox);
 
15717            syserr > 0 ? strerror(syserr) : 
"unable to fork()");
 
15728    memset(&svm, 0, 
sizeof(svm));
 
15729    if (!(vmu = 
find_user(&svm, testcontext, testmailbox)) &&
 
15739    memset(&vms, 0, 
sizeof(vms));
 
15742    for (i = 0; i < 3; i++) {
 
15743        create_dirpath(tmp[i].dir, 
sizeof(tmp[i].dir), testcontext, testmailbox, folders[i]);
 
15744        make_file(tmp[i].file, 
sizeof(tmp[i].file), tmp[i].dir, 0);
 
15745        snprintf(tmp[i].txtfile, 
sizeof(tmp[i].txtfile), 
"%s.txt", tmp[i].file);
 
15748            snprintf(syscmd, 
sizeof(syscmd), 
"cp \"%s/sounds/en/%s.gsm\" \"%s/%s/%s/%s/msg0000.gsm\"", 
ast_config_AST_DATA_DIR, origweasels,
 
15752                    syserr > 0 ? strerror(syserr) : 
"unable to fork()");
 
15761        if ((txt = fopen(tmp[i].txtfile, 
"w+"))) {
 
15762            fprintf(txt, 
"; just a stub\n[message]\nflag=%s\n", strcmp(folders[i], 
"Urgent") ? 
"" : 
"Urgent");
 
15770        STORE(tmp[i].dir, testmailbox, testcontext, 0, chan, vmu, 
"gsm", 600, &vms, strcmp(folders[i], 
"Urgent") ? 
"" : 
"Urgent", 
NULL);
 
15773        for (j = 0; j < 3; j++) {
 
15782        new = old = urgent = 0;
 
15786        } 
else if (old != expected_results[i][3 + 0] || 
new != expected_results[i][3 + 2]) {
 
15788                testspec, old, expected_results[i][3 + 0], 
new, expected_results[i][3 + 2]);
 
15792        new = old = urgent = 0;
 
15796        } 
else if (old != expected_results[i][6 + 0] ||
 
15797                urgent != expected_results[i][6 + 1] ||
 
15798                   new != expected_results[i][6 + 2]    ) {
 
15799            ast_test_status_update(
test, 
"inboxcount2(%s) returned old=%d (expected %d), urgent=%d (expected %d), and new=%d (expected %d)\n",
 
15800                testspec, old, expected_results[i][6 + 0], urgent, expected_results[i][6 + 1], 
new, expected_results[i][6 + 2]);
 
15804        new = old = urgent = 0;
 
15805        for (j = 0; j < 3; j++) {
 
15808                    testspec, folders[j], 
ast_app_messagecount(testspec, folders[j]), expected_results[i][9 + j]);
 
15814    for (i = 0; i < 3; i++) {
 
15818        DELETE(tmp[i].dir, 0, tmp[i].file, vmu);
 
15834    snprintf(syscmd, 
sizeof(syscmd), 
"rm -rf \"%s%s/%s\"", 
VM_SPOOL_DIR, testcontext, testmailbox);
 
15837            syserr > 0 ? strerror(syserr) : 
"unable to fork()");
 
15848    char testcontext[] = 
"test";
 
15849    char testmailbox[] = 
"00000000";
 
15850    char from[] = 
"test@example.net", cidnum[] = 
"1234", cidname[] = 
"Mark Spencer", format[] = 
"gsm";
 
15851    char attach[256], attach2[256];
 
15852    char buf[256] = 
""; 
 
15860        enum { INT, FLAGVAL, STATIC, STRPTR } 
type;
 
15867        { 
"plain jane config", STATIC, vmus.
password, .u.strval = 
"1234" }, 
 
15868        { 
"emailsubject", STRPTR, vmus.
emailsubject, .u.strval = 
"Oogly boogly\xf8koogly with what appears to be UTF-8" },
 
15869        { 
"emailbody", STRPTR, vmus.
emailbody, .u.strval = 
"This is a test\n\twith multiple\nlines\nwithin\n" },
 
15870        { 
"serveremail", STATIC, vmus.
serveremail, .u.strval = 
"\"\xf8Something\xe8that\xd8seems to have UTF-8 chars\" <test@example.net>" },
 
15871        { 
"attachment flag", FLAGVAL, &vmus.
flags, .u.intval = 
VM_ATTACH },
 
15872        { 
"attach2", STRPTR, attach2, .u.strval = 
"" },
 
15873        { 
"attach", STRPTR, attach, .u.strval = 
"" },
 
15879        info->name = 
"test_voicemail_notify_endl";
 
15880        info->category = 
"/apps/app_voicemail/";
 
15881        info->summary = 
"Test Voicemail notification end-of-line";
 
15882        info->description =
 
15883            "Verify that notification emails use a consistent end-of-line character";
 
15892    if (!(vmu = 
find_user(&vmus, testcontext, testmailbox)) &&
 
15898    if (vmu != &vmus && !(vmu = 
find_user(&vmus, testcontext, testmailbox))) {
 
15910    for (which = 0; which < 
ARRAY_LEN(test_items); which++) {
 
15913        if (ftruncate(fileno(file), 0)) {
 
15920        if (test_items[which].
type == INT) {
 
15921            *((
int *) test_items[which].location) = test_items[which].u.intval;
 
15922        } 
else if (test_items[which].
type == FLAGVAL) {
 
15928        } 
else if (test_items[which].
type == STATIC) {
 
15929            strcpy(test_items[which].location, test_items[which].u.strval);
 
15930        } 
else if (test_items[which].
type == STRPTR) {
 
15931            test_items[which].location = test_items[which].u.strval;
 
15934        make_email_file(file, from, vmu, 0, testcontext, testmailbox, 
"INBOX", cidnum, cidname, attach, attach2, format, 999, 1, chan, 
NULL, 0, 
NULL, 
NULL);
 
15936        while (fgets(
buf, 
sizeof(
buf), file)) {
 
15938            (strlen(
buf) > 1 &&
 
15940            buf[strlen(
buf) - 2] != 
'\r' 
15942            buf[strlen(
buf) - 2] == 
'\r' 
15945            || 
buf[strlen(
buf) - 1] != 
'\n') {
 
15968        info->name = 
"test_voicemail_load_config";
 
15969        info->category = 
"/apps/app_voicemail/";
 
15970        info->summary = 
"Test loading Voicemail config";
 
15971        info->description =
 
15972            "Verify that configuration is loaded consistently. " 
15973            "This is to test regressions of ASTERISK-18838 where it was noticed that " 
15974            "some options were loaded after the mailboxes were instantiated, causing " 
15975            "those options not to be set correctly.";
 
15985    if (!(file = fdopen(fd, 
"w"))) {
 
15990    fputs(
"[general]\ncallback=somecontext\nlocale=de_DE.UTF-8\ntz=european\n[test]", file);
 
15991    fputs(
"00000001 => 9999,Mr. Test,,,callback=othercontext|locale=nl_NL.UTF-8|tz=central\n", file);
 
15992    fputs(
"00000002 => 9999,Mrs. Test\n", file);
 
16000    load_config_from_memory(1, cfg);
 
16003#define CHECK(u, attr, value) else if (strcmp(u->attr, value)) { \ 
16004    ast_test_status_update(test, "mailbox %s should have %s '%s', but has '%s'\n", \ 
16005    u->mailbox, #attr, value, u->attr); res = AST_TEST_FAIL; break; } 
16009        if (!strcmp(vmu->
mailbox, 
"00000001")) {
 
16011            CHECK(vmu, 
callback, 
"othercontext")
 
16012            CHECK(vmu, 
locale, "nl_NL.UTF-8")
 
16013            CHECK(vmu, 
zonetag, "central")
 
16014        } else 
if (!strcmp(vmu->mailbox, "00000002")) {
 
16016            CHECK(vmu, 
callback, 
"somecontext")
 
16017            CHECK(vmu, 
locale, "de_DE.UTF-8")
 
16018            CHECK(vmu, 
zonetag, "european")
 
16037    const char testcontext[] = 
"test";
 
16038    const char testmailbox[] = 
"00000000";
 
16039    const char vminfo_cmd[] = 
"VM_INFO";
 
16040    char vminfo_buf[256], vminfo_args[256];
 
16043    int test_counter = 0;
 
16046        char *vminfo_test_args;
 
16047        char *vminfo_expected;
 
16051        { 
"00000000@test,badparam", 
"", -1 },   
 
16052        { 
"00000000@test", 
"", -1 },        
 
16053        { 
"00000000@test,exists", 
"1", 0 },
 
16054        { 
"11111111@test,exists", 
"0", 0 }, 
 
16055        { 
"00000000@test,email", 
"vm-info-test@example.net", 0 },
 
16056        { 
"11111111@test,email", 
"", 0 },   
 
16057        { 
"00000000@test,fullname", 
"Test Framework Mailbox", 0 },
 
16058        { 
"00000000@test,pager", 
"vm-info-pager-test@example.net", 0 },
 
16059        { 
"00000000@test,locale", 
"en_US", 0 },
 
16060        { 
"00000000@test,tz", 
"central", 0 },
 
16061        { 
"00000000@test,language", 
"en", 0 },
 
16062        { 
"00000000@test,password", 
"9876", 0 },
 
16067            info->name = 
"test_voicemail_vm_info";
 
16068            info->category = 
"/apps/app_voicemail/";
 
16069            info->summary = 
"VM_INFO unit test";
 
16070            info->description =
 
16071                "This tests passing various parameters to VM_INFO";
 
16104    for (test_counter = 0; test_counter < 
ARRAY_LEN(test_items); test_counter++) {
 
16105        ast_copy_string(vminfo_args, test_items[test_counter].vminfo_test_args, 
sizeof(vminfo_args));
 
16106        test_ret = 
acf_vm_info(chan, vminfo_cmd, vminfo_args, vminfo_buf, 
sizeof(vminfo_buf));
 
16107        if (strcmp(vminfo_buf, test_items[test_counter].vminfo_expected)) {
 
16108            ast_test_status_update(
test, 
"VM_INFO response was: '%s', but expected: '%s'\n", vminfo_buf, test_items[test_counter].vminfo_expected);
 
16111        if (!(test_ret == test_items[test_counter].vminfo_ret)) {
 
16112            ast_test_status_update(
test, 
"VM_INFO return code was: '%i', but expected '%i'\n", test_ret, test_items[test_counter].vminfo_ret);
 
16170#ifdef TEST_FRAMEWORK 
16181#ifdef TEST_FRAMEWORK 
16182    ast_uninstall_vm_test_functions();
 
 
16213    prnt(where, 
"Alias: %s Mailbox: %s", mapping->
alias, mapping->
mailbox);
 
 
16243        alias_mailbox_mapping_hash_fn, 
NULL, alias_mailbox_mapping_cmp_fn);
 
16245        ast_log(
LOG_ERROR, 
"Unable to create alias_mailbox_mappings container\n");
 
16251        ast_log(
LOG_ERROR, 
"Unable to register alias_mailbox_mappings container\n");
 
16258        mailbox_alias_mapping_hash_fn, 
NULL, mailbox_alias_mapping_cmp_fn);
 
16260        ast_log(
LOG_ERROR, 
"Unable to create mailbox_alias_mappings container\n");
 
16268        ast_log(
LOG_ERROR, 
"Unable to register mailbox_alias_mappings container\n");
 
16301#ifdef TEST_FRAMEWORK 
16311        ast_log(
LOG_ERROR, 
"Failure registering applications, functions or tests\n");
 
16334#ifdef TEST_FRAMEWORK 
16335    ast_install_vm_test_functions(vm_test_create_user, vm_test_destroy_user);
 
 
16347    char destination[80] = 
"";
 
16351        ast_verb(3, 
"Destination number will be entered manually\n");
 
16352        while (retries < 3 && cmd != 
't') {
 
16353            destination[1] = 
'\0';
 
16362                    destination[0] = cmd;
 
16371                    ast_verb(3, 
"User hit '*' to cancel outgoing call\n");
 
16374                if ((cmd = 
ast_readstring(chan, destination + strlen(destination), 
sizeof(destination) - 1, 6000, 10000, 
"#")) < 0)
 
16380                isprint(cmd) ? cmd : 
'?', isprint(cmd) ? cmd : 
'?');
 
16382        if (retries >= 3) {
 
16387        ast_verb(3, 
"Destination number is CID number '%s'\n", num);
 
16392        if (destination[strlen(destination) -1 ] == 
'*')
 
16394        ast_verb(3, 
"Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, 
ast_channel_context(chan));
 
 
16421    const char *origtime, *context;
 
16432    snprintf(filename, 
sizeof(filename), 
"%s.txt", vms->
fn);
 
16467        while ((res > -1) && (res != 
't')) {
 
16491                    ast_verb(3, 
"Caller can not specify callback number - no dialout context available\n");
 
16513                    ast_verb(3, 
"Confirm CID number '%s' is number to use for callback\n", num);
 
16544                    isprint(res) ? res : 
'?', isprint(res) ? res : 
'?');
 
16550            else if (res == 
'*')
 
16562            ast_verb(3, 
"No CID number available, no reply sent\n");
 
16569            memset(&vmu2, 0, 
sizeof(vmu2));
 
16574                snprintf(mailbox, 
sizeof(mailbox), 
"%s@%s", num, vmu->
context);
 
16576                ast_verb(3, 
"Leaving voicemail for '%s' in context '%s'\n", num, vmu->
context);
 
16578                memset(&leave_options, 0, 
sizeof(leave_options));
 
16589                ast_verb(3, 
"No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->
context);
 
16603#ifndef IMAP_STORAGE 
16606        vms->
heard[msg] = 1;
 
 
16614            int outsidecaller, 
struct ast_vm_user *vmu, 
int *duration, 
int *sound_duration, 
const char *unlockdir,
 
16620    int max_attempts = 3;
 
16623    int msg_exists = 0;
 
16624    signed char zero_gain = 0;
 
16626    char *acceptdtmf = 
"#";
 
16627    char *canceldtmf = 
"";
 
16628    int canceleddtmf = 0;
 
16629    SCOPE_ENTER(3, 
"%s: rf: %s fmt: %s type: %s vmu: %s\n",
 
16630        ast_channel_name(chan), recordfile, fmt, outsidecaller ? 
"msg" : 
"greeting",
 
16635    if (duration == 
NULL) {
 
16639    if (!outsidecaller)
 
16640        snprintf(tempfile, 
sizeof(tempfile), 
"%s.tmp", recordfile);
 
16646    while ((cmd >= 0) && (cmd != 
't')) {
 
16655                ast_verb(3, 
"Saving message as is\n");
 
16656                if (!outsidecaller) {
 
16657                    ast_trace(-1, 
"Renaming greeting '%s' to '%s'\n", tempfile, recordfile);
 
16660                if (!forwardintro) {
 
16663                if (!outsidecaller) {
 
16665                    ast_trace(-1, 
"Saving greeting '%s'\n", recordfile);
 
16666                    SCOPE_CALL(-1, 
STORE, recordfile, vmu->
mailbox, vmu->
context, -1, chan, vmu, fmt, *duration, vms, 
flag, msg_id);
 
16674            ast_verb(3, 
"Reviewing the message\n");
 
16675            ast_trace(-1, 
"Reviewing '%s'\n", tempfile);
 
16682                ast_verb(3, 
"Re-recording the message\n");
 
16684                ast_verb(3, 
"Recording the message\n");
 
16686            if (recorded && outsidecaller) {
 
16687                if (forwardintro) {
 
16697                SCOPE_EXIT_RTN_VALUE(cmd, 
"User hung up before message could be rerecorded.  Deleted '%s'\n", tempfile);
 
16705            ast_trace(-1, 
"Recording '%s'\n", tempfile);
 
16706            cmd = 
ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, 0, 
silencethreshold, 
maxsilence, unlockdir, acceptdtmf, canceldtmf, 0, 
AST_RECORD_IF_EXISTS_OVERWRITE);
 
16707            if (strchr(canceldtmf, cmd)) {
 
16715                if (!outsidecaller) {
 
16720                    outsidecaller ? 
"Saved message " : 
"Deleted greeting \n", tempfile);
 
16724            } 
else if (cmd == 
'*') {
 
16727            } 
else if (vmu->review && sound_duration && (*sound_duration < 5)) {
 
16729                ast_verb(3, 
"Message too short\n");
 
16733            } 
else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (
maxsilence + 3))) {
 
16735                ast_verb(3, 
"Nothing recorded\n");
 
16752                    ast_verb(3, 
"marking message as Urgent\n");
 
16754                    strcpy(
flag, 
"Urgent");
 
16756                    ast_verb(3, 
"UNmarking message as Urgent\n");
 
16783            if (outsidecaller) {
 
16795            if (msg_exists || recorded) {
 
16796                ast_trace(-1, 
"Reviewing '%s'\n", tempfile);
 
16801                    ast_trace(-1, 
"Saving '%s' to '%s'\n", tempfile, recordfile);
 
16805                } 
else if (cmd == 
'4') {
 
16808                        strcpy(
flag, 
"Urgent");
 
16813                    ast_trace(-1, 
"Deleting '%s'\n", tempfile);
 
16857            if (attempts > max_attempts) {
 
16862    if (!outsidecaller && (cmd == -1 || cmd == 
't')) {
 
16864        ast_trace(-1, 
"Deleting '%s' on hangup or timeout\n", tempfile);
 
16868    if (cmd != 
't' && outsidecaller)
 
 
16878    if (!(msg_snapshot = 
ast_calloc(1, 
sizeof(*msg_snapshot)))) {
 
16887    return msg_snapshot;
 
 
16898#ifdef TEST_FRAMEWORK 
16900static int vm_test_destroy_user(
const char *context, 
const char *mailbox)
 
16918static int vm_test_create_user(
const char *
context, 
const char *
mailbox)
 
16945    int snapshot_index,
 
16961        snprintf(filename, 
sizeof(filename), 
"%s.txt", vms->
fn);
 
16985                            filename, 
id, 
sizeof(
id), vmu, mailbox_index))) {
 
17016        switch (sort_val) {
 
17029                if (descending && 
val >= 0) {
 
17033                } 
else if (!descending && 
val <= 0) {
 
 
17058    const char *context,
 
17059    const char *folder,
 
17062    int combine_INBOX_and_OLD)
 
17069    int this_index_only = -1;
 
17076        ast_log(
LOG_WARNING, 
"Cannot create a mailbox snapshot since no mailbox was specified\n");
 
17080    memset(&vmus, 0, 
sizeof(vmus));
 
17086                this_index_only = i;
 
17090        if (this_index_only == -1) {
 
17101    if (!(mailbox_snapshot = 
ast_calloc(1, 
sizeof(*mailbox_snapshot)))) {
 
17115    for (i = 0; i < mailbox_snapshot->
folders; i++) {
 
17116        int msg_folder_index = i;
 
17123        if (!(this_index_only == -1 || this_index_only == i || (this_index_only == inbox_index && combine_INBOX_and_OLD && (i == old_index || i == urgent_index)))) {
 
17128        if (combine_INBOX_and_OLD && (i == old_index || i == urgent_index)) {
 
17129            msg_folder_index = inbox_index;
 
17132        memset(&vms, 0, 
sizeof(vms));
 
17140            goto snapshot_cleanup;
 
17148                goto snapshot_cleanup;
 
17154            goto snapshot_cleanup;
 
17166        vmstate_delete(&vms);
 
17171    return mailbox_snapshot;
 
 
17179    for (i = 0; i < mailbox_snapshot->
folders; i++) {
 
 
17212    for (i = 0; i < num_msgs; ++i) {
 
17213        const char *
msg_id = msg_ids[i];
 
17216            const char *other_msg_id;
 
17222            snprintf(filename, 
sizeof(filename), 
"%s.txt", vms->
fn);
 
17233            if (!
ast_strlen_zero(other_msg_id) && !strcmp(other_msg_id, msg_id)) {
 
17238                msg_nums[i] = vms->
curmsg;
 
 
17259    int new = 0, old = 0, urgent = 0;
 
17260    char ext_context[1024];
 
17262    snprintf(ext_context, 
sizeof(ext_context), 
"%s@%s", vmu->
mailbox, vmu->
context);
 
 
17269    const char *from_context,
 
17270    const char *from_folder,
 
17271    const char *to_mailbox,
 
17272    const char *to_context,
 
17273    const char *to_folder,
 
17275    const char *msg_ids [],
 
17284    int from_folder_index;
 
17291        ast_log(
LOG_WARNING, 
"Cannot forward message because either the from or to mailbox was not specified\n");
 
17296        ast_log(
LOG_WARNING, 
"Invalid number of messages specified to forward: %zu\n", num_msgs);
 
17301        ast_log(
LOG_WARNING, 
"Cannot forward message because the from_folder or to_folder was not specified\n");
 
17305    memset(&vmus, 0, 
sizeof(vmus));
 
17306    memset(&to_vmus, 0, 
sizeof(to_vmus));
 
17307    memset(&from_vms, 0, 
sizeof(from_vms));
 
17310    if (from_folder_index == -1) {
 
17318    if (!(vmu = 
find_user(&vmus, from_context, from_mailbox))) {
 
17319        ast_log(
LOG_WARNING, 
"Can't find voicemail user to forward from (%s@%s)\n", from_mailbox, from_context);
 
17323    if (!(to_vmu = 
find_user(&to_vmus, to_context, to_mailbox))) {
 
17324        ast_log(
LOG_WARNING, 
"Can't find voicemail user to forward to (%s@%s)\n", to_mailbox, to_context);
 
17334    if ((res = 
open_mailbox(&from_vms, vmu, from_folder_index)) < 0) {
 
17337        goto vm_forward_cleanup;
 
17342    if ((from_vms.
lastmsg + 1) < num_msgs) {
 
17343        ast_log(
LOG_WARNING, 
"Folder %s has less than %zu messages\n", from_folder, num_msgs);
 
17345        goto vm_forward_cleanup;
 
17348    msg_nums = 
ast_alloca(
sizeof(
int) * num_msgs);
 
17351        goto vm_forward_cleanup;
 
17355    for (i = 0; i < num_msgs; i++) {
 
17356        int cur_msg = msg_nums[i];
 
17361        snprintf(filename, 
sizeof(filename), 
"%s.txt", from_vms.
fn);
 
17373            duration = atoi(
value);
 
17379            from_vms.
deleted[cur_msg] = 1;
 
17388        goto vm_forward_cleanup;
 
17398        vmstate_delete(&from_vms);
 
 
17412    const char *context,
 
17414    const char *oldfolder,
 
17415    const char *old_msg_ids [],
 
17416    const char *newfolder)
 
17420    int old_folder_index;
 
17421    int new_folder_index;
 
17433        ast_log(
LOG_WARNING, 
"Invalid number of messages specified to move: %zu\n", num_msgs);
 
17438        ast_log(
LOG_WARNING, 
"Cannot move message because either oldfolder or newfolder was not specified\n");
 
17445    memset(&vmus, 0, 
sizeof(vmus));
 
17446    memset(&vms, 0, 
sizeof(vms));
 
17448    if (old_folder_index == -1 || new_folder_index == -1) {
 
17461    if ((res = 
open_mailbox(&vms, vmu, old_folder_index)) < 0) {
 
17464        goto vm_move_cleanup;
 
17469    if ((vms.
lastmsg + 1) < num_msgs) {
 
17470        ast_log(
LOG_WARNING, 
"Folder %s has less than %zu messages\n", oldfolder, num_msgs);
 
17472        goto vm_move_cleanup;
 
17475    old_msg_nums = 
ast_alloca(
sizeof(
int) * num_msgs);
 
17478        goto vm_move_cleanup;
 
17482    for (i = 0; i < num_msgs; ++i) {
 
17485            goto vm_move_cleanup;
 
17487        vms.
deleted[old_msg_nums[i]] = 1;
 
17493        goto vm_move_cleanup;
 
17503        vmstate_delete(&vms);
 
 
17518    const char *folder,
 
17519    const char *msgs[])
 
17535        ast_log(
LOG_WARNING, 
"Invalid number of messages specified to remove: %zu\n", num_msgs);
 
17544    memset(&vmus, 0, 
sizeof(vmus));
 
17545    memset(&vms, 0, 
sizeof(vms));
 
17548    if (folder_index == -1) {
 
17563    if ((res = 
open_mailbox(&vms, vmu, folder_index)) < 0) {
 
17566        goto vm_remove_cleanup;
 
17571    if ((vms.
lastmsg + 1) < num_msgs) {
 
17574        goto vm_remove_cleanup;
 
17577    msg_nums = 
ast_alloca(
sizeof(
int) * num_msgs);
 
17580        goto vm_remove_cleanup;
 
17583    for (i = 0; i < num_msgs; i++) {
 
17584        vms.
deleted[msg_nums[i]] = 1;
 
17591        goto vm_remove_cleanup;
 
17601        vmstate_delete(&vms);
 
 
17616    const char *folder,
 
17617    const char *msg_id,
 
17642        ast_log(
LOG_WARNING, 
"Cannot play message because no message number was specified\n");
 
17646    memset(&vmus, 0, 
sizeof(vmus));
 
17647    memset(&vms, 0, 
sizeof(vms));
 
17650        context = 
"default";
 
17653    if (!(vmu = 
find_user(&vmus, context, mailbox))) {
 
17662        goto play2_msg_cleanup;
 
17668        goto play2_msg_cleanup;
 
17673    snprintf(filename, 
sizeof(filename), 
"%s.txt", vms.
fn);
 
17680        goto play2_msg_cleanup;
 
17683        duration = atoi(
value);
 
17696        cb(chan, vms.
fn, duration);
 
17697    } 
else if ((
wait_file(chan, &vms, vms.
fn)) < 0) {
 
17715        vmstate_delete(&vms);
 
 
17736    .optional_modules = 
"res_adsi,res_smdi",
 
ADSI Support (built upon Caller*ID)
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
int ast_adsi_load_soft_key(unsigned char *buf, int key, const char *llabel, const char *slabel, char *ret, int data)
Creates "load soft key" parameters.
#define ADSI_MSG_DOWNLOAD
int ast_adsi_data_mode(unsigned char *buf)
Puts CPE in data mode.
int ast_adsi_unload_session(struct ast_channel *chan)
int ast_adsi_begin_download(struct ast_channel *chan, char *service, unsigned char *fdn, unsigned char *sec, int version)
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
int ast_adsi_input_control(unsigned char *buf, int page, int line, int display, int format, int just)
Set input information.
int ast_adsi_input_format(unsigned char *buf, int num, int dir, int wrap, char *format1, char *format2)
Set input format.
int ast_adsi_load_session(struct ast_channel *chan, unsigned char *app, int ver, int data)
Check if scripts for a given app are already loaded. Version may be -1, if any version is okay,...
int ast_adsi_end_download(struct ast_channel *chan)
int ast_adsi_download_disconnect(unsigned char *buf)
Disconnects (and hopefully saves) a downloaded script.
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
#define ADSI_DIR_FROM_LEFT
int ast_adsi_set_keys(unsigned char *buf, unsigned char *keys)
Set which soft keys should be displayed.
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
void ast_cli_unregister_multiple(void)
static int load_config(void)
struct sla_ringing_trunk * last
#define VMBOX_STRING_DATA_FORMAT
static char * vm_check_password_shell(char *command, char *buf, size_t len)
static int vm_browse_messages_vi(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Vietnamese syntax for 'You have N messages' greeting.
static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box, int *newmsg, int move)
static char pagerfromstring[100]
static char vm_password[80]
static char vm_invalid_password[80]
#define VM_ODBC_AUDIO_ON_DISK
static char * handle_voicemail_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Show a list of voicemail users in the CLI.
static int vm_browse_messages_en(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Default English syntax for 'You have N messages' greeting.
static char listen_control_reverse_key[12]
#define MAX_VM_CONTEXT_LEN
#define EXISTS(a, b, c, d)
static int vm_intro_pl(struct ast_channel *chan, struct vm_state *vms)
static void adsi_password(struct ast_channel *chan)
static char serveremail[80]
static int get_folder(struct ast_channel *chan, int start)
get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized
#define VMSTATE_MAX_MSG_ARRAY
static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
Prompts the user and records a voicemail to a mailbox.
static void adsi_folders(struct ast_channel *chan, int start, char *label)
static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
static int mwi_handle_unsubscribe2(void *data)
#define VOICEMAIL_DIR_MODE
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
static int manager_voicemail_refresh(struct mansession *s, const struct message *m)
static int inprocess_hash_fn(const void *obj, const int flags)
static struct ast_custom_function vm_info_acf
static const char * ast_str_encode_mime(struct ast_str **end, ssize_t maxlen, const char *start, size_t preamble, size_t postamble)
Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain ...
static int show_messages_for_mailbox(struct ast_cli_args *a)
static int vm_msg_play(struct ast_channel *chan, const char *mailbox, const char *context, const char *folder, const char *msg_num, ast_vm_msg_play_cb cb)
static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag, const char *msg_id)
Creates the email file to be sent to indicate a new voicemail exists for a user.
static int manager_list_voicemail_users(struct mansession *s, const struct message *m)
Manager list voicemail users command.
#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY
static int vm_delete(char *file)
Removes the voicemail sound and information file.
static int wait_file2(struct ast_channel *chan, struct vm_state *vms, char *file)
static int msg_id_incrementor
static const struct ast_vm_functions vm_table
static void free_zone(struct vm_zone *z)
static void adsi_begin(struct ast_channel *chan, int *useadsi)
static char * handle_voicemail_show_mailbox(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void read_password_from_file(const char *secretfn, char *password, int passwordlen)
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
static void apply_options_full(struct ast_vm_user *retval, struct ast_variable *var)
Loads the options specific to a voicemail user.
static void populate_defaults(struct ast_vm_user *vmu)
Sets default voicemail system options to a voicemail user.
static struct ast_taskprocessor * mwi_subscription_tps
static int vm_browse_messages_zh(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Chinese (Taiwan)syntax for 'You have N messages' greeting.
static char vm_newpassword[80]
static int vm_intro_he(struct ast_channel *chan, struct vm_state *vms)
static int vm_execmain(struct ast_channel *chan, const char *data)
static void free_user(struct ast_vm_user *vmu)
static int vm_play_folder_name_gr(struct ast_channel *chan, char *box)
static int vm_instructions_zh(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent, int nodelete)
static int actual_load_config(int reload, struct ast_config *cfg)
static int invent_message(struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes)
static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent, int nodelete)
#define UPDATE_MSG_ID(a, b, c, d, e, f)
static int vm_instructions_en(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent, int nodelete)
#define VM_STRING_HEADER_FORMAT
static void generate_msg_id(char *dst)
Sets the destination string to a uniquely identifying msg_id string.
static struct ast_flags globalflags
static char listen_control_forward_key[12]
static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag, const char *msg_id, int forwardintro)
static int vmauthenticate(struct ast_channel *chan, const char *data)
static int play_message_duration(struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration)
static int vm_browse_messages_pt(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Portuguese syntax for 'You have N messages' greeting.
static char vm_newuser[80]
#define VMBOX_STRING_HEADER_FORMAT
static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag, const char *msg_id)
static const char * ast_str_quote(struct ast_str **buf, ssize_t maxlen, const char *from)
Wraps a character sequence in double quotes, escaping occurrences of quotes within the string.
static ast_mutex_t poll_lock
static int check_mime(const char *str)
Check if the string would need encoding within the MIME standard, to avoid confusing certain mail sof...
static const char * vm_index_to_foldername(int id)
static unsigned char adsisec[4]
static int play_message_category(struct ast_channel *chan, const char *category)
static struct ast_vm_user * find_user_realtime(struct ast_vm_user *ivm, const char *context, const char *mailbox)
Finds a voicemail user from the realtime engine.
static const char * substitute_escapes(const char *value)
static int change_password_realtime(struct ast_vm_user *vmu, const char *password)
Performs a change of the voicemail password in the realtime engine.
static int reset_user_pw(const char *context, const char *mailbox, const char *newpass)
Resets a user password to a specified password.
static int count_messages(struct ast_vm_user *vmu, char *dir)
Find all .txt files - even if they are not in sequence from 0000.
static pthread_t poll_thread
static int vm_intro_multilang(struct ast_channel *chan, struct vm_state *vms, const char message_gender[])
static int vm_exec(struct ast_channel *chan, const char *data)
static struct ast_vm_msg_snapshot * vm_msg_snapshot_alloc(void)
static char * pagersubject
static int manager_voicemail_forward(struct mansession *s, const struct message *m)
static int manager_voicemail_move(struct mansession *s, const struct message *m)
#define COPY(a, b, c, d, e, f, g, h)
static void load_zonemessages(struct ast_config *cfg)
static int vm_browse_messages(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Top level method to invoke the language variant vm_browse_messages_XX function.
static int vm_intro(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int vm_playmsgexec(struct ast_channel *chan, const char *data)
static int vm_intro_de(struct ast_channel *chan, struct vm_state *vms)
static int passwordlocation
static int get_folder_ja(struct ast_channel *chan, int start)
static char vm_mismatch[80]
static void adsi_delete(struct ast_channel *chan, struct vm_state *vms)
static const struct ast_app_option vm_app_options[128]
static char * voicemail_app
static char * playmsg_app
static int vm_browse_messages_es(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Spanish syntax for 'You have N messages' greeting.
static void notify_new_state(struct ast_vm_user *vmu)
static void adsi_message(struct ast_channel *chan, struct vm_state *vms)
#define ASTERISK_USERNAME
static int vm_newuser_setup(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
static char vm_pls_try_again[80]
static int play_message_callerid(struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback, int saycidnumber)
static int write_password_to_file(const char *secretfn, const char *password)
static int wait_file(struct ast_channel *chan, struct vm_state *vms, char *file)
static int append_vmbox_info_astman(struct mansession *s, const struct message *m, struct ast_vm_user *vmu, const char *event_name, const char *actionid)
Append vmbox info string into given astman with event_name.
static int msg_create_from_file(struct ast_vm_recording_data *recdata)
static char * complete_voicemail_show_mailbox(struct ast_cli_args *a)
static const struct ast_vm_greeter_functions vm_greeter_table
static void rename_file(char *sfn, char *dfn)
Renames a message in a mailbox folder.
static int move_message_from_mailbox(struct ast_cli_args *a)
static struct alias_mailbox_mapping * alias_mailbox_mapping_create(const char *alias, const char *mailbox)
static struct ast_vm_mailbox_snapshot * vm_mailbox_snapshot_destroy(struct ast_vm_mailbox_snapshot *mailbox_snapshot)
struct ast_mwi_observer mwi_observer
static char ext_pass_check_cmd[128]
static int vm_intro_pt_BR(struct ast_channel *chan, struct vm_state *vms)
static int append_vmu_info_astman(struct mansession *s, struct ast_vm_user *vmu, const char *event_name, const char *actionid)
Append vmu info string into given astman with event_name.
static int separate_mailbox(char *mailbox_id, char **mailbox, char **context)
static int vm_msg_snapshot_create(struct ast_vm_user *vmu, struct vm_state *vms, struct ast_vm_mailbox_snapshot *mailbox_snapshot, int snapshot_index, int mailbox_index, int descending, enum ast_vm_snapshot_sort_val sort_val)
Create and store off all the msgs in an open mailbox.
static char dialcontext[AST_MAX_CONTEXT]
static int vmsayname_exec(struct ast_channel *chan, const char *data)
#define DEFAULT_POLL_FREQ
static int vm_intro_vi(struct ast_channel *chan, struct vm_state *vms)
static int messagecount(const char *mailbox_id, const char *folder)
static int manager_voicemail_remove(struct mansession *s, const struct message *m)
static void stop_poll_thread(void)
static char aliasescontext[MAX_VM_CONTEXT_LEN]
static int vm_sayname(struct ast_channel *chan, const char *mailbox_id)
#define DELETE(a, b, c, d)
static void print_mappings(void *v_obj, void *where, ao2_prnt_fn *prnt)
static struct ast_cli_entry cli_voicemail[]
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY
static char listen_control_stop_key[12]
static char fromstring[100]
static int vm_browse_messages_ja(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Japanese syntax for 'You have N messages' greeting.
#define PWDCHANGE_INTERNAL
static char * handle_voicemail_forward_message(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int vm_intro_cs(struct ast_channel *chan, struct vm_state *vms)
static void mwi_handle_unsubscribe(const char *id, struct ast_mwi_subscriber *sub)
static int adsi_load_vmail(struct ast_channel *chan, int *useadsi)
static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
The handler for the change password option.
static void * mb_poll_thread(void *data)
static char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64]
static void run_externnotify(const char *context, const char *extension, const char *flag)
static int append_mailbox(const char *context, const char *box, const char *data)
static int vm_lock_path(const char *path)
Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist...
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int vm_intro_nl(struct ast_channel *chan, struct vm_state *vms)
static void adsi_status(struct ast_channel *chan, struct vm_state *vms)
#define DEFAULT_LISTEN_CONTROL_STOP_KEY
static int acf_vm_info(struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len)
static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, int box)
static int vm_intro_zh(struct ast_channel *chan, struct vm_state *vms)
static char emaildateformat[32]
static char vm_reenterpassword[80]
static void adsi_login(struct ast_channel *chan)
static int manager_get_mailbox_summary(struct mansession *s, const struct message *m)
static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain)
The advanced options within a message.
#define MAX_VM_MAILBOX_LEN
static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
static int vm_intro_pt(struct ast_channel *chan, struct vm_state *vms)
static int play_message_by_id_helper(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, const char *msg_id)
static int load_config_force(int reload, int force)
Reload voicemail.conf.
static int saydurationminfo
struct ao2_container * inprocess_container
static int vm_allocate_dh(struct vm_state *vms, struct ast_vm_user *vmu, int count_msg)
static void prep_email_sub_vars(struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, const char *category, const char *flag)
static char * sayname_app
static void free_user_final(struct ast_vm_user *vmu)
static int vm_instructions_ja(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent, int nodelete)
static int message_range_and_existence_check(struct vm_state *vms, const char *msg_ids[], size_t num_msgs, int *msg_nums, struct ast_vm_user *vmu)
common bounds checking and existence check for Voicemail API functions.
static int get_folder2(struct ast_channel *chan, char *fn, int start)
plays a prompt and waits for a keypress.
static int vm_msg_forward(const char *from_mailbox, const char *from_context, const char *from_folder, const char *to_mailbox, const char *to_context, const char *to_folder, size_t num_msgs, const char *msg_ids[], int delete_old)
static void adsi_goodbye(struct ast_channel *chan)
#define HVSU_OUTPUT_FORMAT
static char ext_pass_cmd[128]
static int is_valid_dtmf(const char *key)
Determines if a DTMF key entered is valid.
static char pagerdateformat[32]
static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
The handler for 'record a temporary greeting'.
static int get_folder_by_name(const char *name)
#define HVSZ_OUTPUT_FORMAT
static char * emailsubject
static int inprocess_count(const char *context, const char *mailbox, int delta)
static struct ast_vm_user * find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
Finds a voicemail user from the users file or the realtime engine.
static struct ao2_container * mailbox_alias_mappings
static int make_dir(char *dest, int len, const char *context, const char *ext, const char *folder)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
static void apply_options(struct ast_vm_user *vmu, const char *options)
Destructively Parse options and apply.
static int add_email_attachment(FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum)
static char externnotify[160]
static int adsi_logo(unsigned char *buf)
static int play_message_datetime(struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename)
static unsigned char poll_thread_run
static char listen_control_restart_key[12]
static int add_message_id(struct ast_config *msg_cfg, char *dir, int msg, char *filename, char *id, size_t id_size, struct ast_vm_user *vmu, int folder)
static int play_message_by_id(struct ast_channel *chan, const char *mailbox, const char *context, const char *msg_id)
Finds a message in a specific mailbox by msg_id and plays it to the channel.
static int create_dirpath(char *dest, int len, const char *context, const char *ext, const char *folder)
basically mkdir -p $dest/$context/$ext/$folder
#define MAX_VM_MBOX_ID_LEN
static char * handle_voicemail_show_aliases(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Show a list of voicemail zones in the CLI.
static char * handle_voicemail_show_zones(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Show a list of voicemail zones in the CLI.
static void copy_plain_file(char *frompath, char *topath)
Copies a voicemail information (envelope) file.
static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts, char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag)
presents the option to prepend to an existing message when forwarding it.
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY
#define MAX_NUM_CID_CONTEXTS
static int vm_play_folder_name_pl(struct ast_channel *chan, char *box)
static char * complete_voicemail_show_users(const char *line, const char *word, int pos, int state)
static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
@ OPT_PWLOC_VOICEMAILCONF
static char vm_prepend_timeout[80]
static int vm_authenticate(struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int max_logins, int silent)
#define RETRIEVE(a, b, c, d)
static int inprocess_cmp_fn(void *obj, void *arg, int flags)
static int vm_intro_en(struct ast_channel *chan, struct vm_state *vms)
static char VM_SPOOL_DIR[PATH_MAX]
static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
#define SMDI_MWI_WAIT_TIMEOUT
static char callcontext[AST_MAX_CONTEXT]
static void mwi_handle_subscribe(const char *id, struct ast_mwi_subscriber *sub)
static int vm_intro_da(struct ast_channel *chan, struct vm_state *vms)
static void vm_change_password_shell(struct ast_vm_user *vmu, char *newpassword)
static int vm_intro_fr(struct ast_channel *chan, struct vm_state *vms)
static int show_mailbox_snapshot(struct ast_cli_args *a)
static int vm_browse_messages_it(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Italian syntax for 'You have N messages' greeting.
static int vm_msg_remove(const char *mailbox, const char *context, size_t num_msgs, const char *folder, const char *msgs[])
static char listen_control_pause_key[12]
static int copy(char *infile, char *outfile)
Utility function to copy a file.
static int silencethreshold
static void start_poll_thread(void)
#define MAX_MAIL_BODY_CONTENT_SIZE
static char * strip_control_and_high(const char *input, char *buf, size_t buflen)
Strips control and non 7-bit clean characters from input string.
#define RENAME(a, b, c, d, e, f, g, h)
static int load_module(void)
Load the module.
static char * handle_voicemail_move_message(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int vm_browse_messages_he(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static unsigned int poll_mailboxes
static int poll_subscribed_mailbox(struct ast_mwi_state *mwi_state, void *data)
static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag)
static int forward_message_from_mailbox(struct ast_cli_args *a)
#define STORE(a, b, c, d, e, f, g, h, i, j, k)
static int vm_intro_is(struct ast_channel *chan, struct vm_state *vms)
static char * complete_voicemail_move_message(struct ast_cli_args *a, int maxpos)
static char * handle_voicemail_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Reload voicemail configuration from the CLI.
static unsigned int poll_freq
static int resequence_mailbox(struct ast_vm_user *vmu, char *dir, int stopcount)
static int last_message_index(char *dir)
Determines the highest message number in use for a given user and mailbox folder.
static ast_cond_t poll_cond
static void adsi_status2(struct ast_channel *chan, struct vm_state *vms)
static int unload_module(void)
static void free_vm_zones(void)
Free the zones structure.
static int mwi_handle_subscribe2(void *data)
static int forward_message(struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int is_new_message, signed char record_gain, int urgent)
Sends a voicemail message to a mailbox recipient.
static int vm_intro_es(struct ast_channel *chan, struct vm_state *vms)
#define PWDCHANGE_EXTERNAL
static struct ast_vm_user * find_or_create(const char *context, const char *box)
static unsigned char adsifdn[4]
static void queue_mwi_event(const char *channel_id, const char *box, int urgent, int new, int old)
static int manager_status_voicemail_user(struct mansession *s, const struct message *m)
#define VOICEMAIL_FILE_MODE
static char * handle_voicemail_remove_message(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define LAST_MSG_INDEX(a)
static void load_aliases(struct ast_config *cfg)
static struct ao2_container * alias_mailbox_mappings
static int vm_play_folder_name(struct ast_channel *chan, char *mbox)
static const struct ast_tm * vmu_tm(const struct ast_vm_user *vmu, struct ast_tm *tm)
fill in *tm for current time according to the proper timezone, if any.
static int vm_play_folder_name_ua(struct ast_channel *chan, char *box)
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY
static char * show_users_realtime(int fd, const char *context)
static int remove_message_from_mailbox(struct ast_cli_args *a)
static int has_voicemail(const char *mailbox, const char *folder)
Determines if the given folder has messages.
static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag)
Sends email notification that a user has a new voicemail waiting for them.
#define VM_EMAIL_EXT_RECS
static struct ast_vm_mailbox_snapshot * vm_mailbox_snapshot_create(const char *mailbox, const char *context, const char *folder, int descending, enum ast_vm_snapshot_sort_val sort_val, int combine_INBOX_and_OLD)
static int manager_match_mailbox(struct ast_mwi_state *mwi_state, void *data)
static int vm_intro_ja(struct ast_channel *chan, struct vm_state *vms)
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
Check the given mailbox's message count.
static char exitcontext[AST_MAX_CONTEXT]
static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
static int vm_msg_move(const char *mailbox, const char *context, size_t num_msgs, const char *oldfolder, const char *old_msg_ids[], const char *newfolder)
static int sayname(struct ast_channel *chan, const char *mailbox, const char *context)
static int get_date(char *s, int len)
Gets the current date and time, as formatted string.
static const char *const mailbox_folders[]
static int show_mailbox_details(struct ast_cli_args *a)
static const char * mbox(struct ast_vm_user *vmu, int id)
static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir, const char *flag, const char *dest_folder)
Copies a message from one mailbox to another.
static char * vmauthenticate_app
static int vm_play_folder_name_ja(struct ast_channel *chan, char *box)
#define force_reload_config()
Forcibly reload voicemail.conf, even if it has not changed. This is necessary after running unit test...
static int vm_intro_se(struct ast_channel *chan, struct vm_state *vms)
static void apply_option(struct ast_vm_user *vmu, const char *var, const char *value)
Sets a specific property value.
static char vm_passchanged[80]
static struct ast_vm_msg_snapshot * vm_msg_snapshot_destroy(struct ast_vm_msg_snapshot *msg_snapshot)
static char * voicemailmain_app
#define ALIASES_OUTPUT_FORMAT
static int vm_intro_it(struct ast_channel *chan, struct vm_state *vms)
static int vm_browse_messages_gr(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Greek syntax for 'You have N messages' greeting.
static struct ast_smdi_interface * smdi_iface
static int vm_intro_gr(struct ast_channel *chan, struct vm_state *vms)
static void free_vm_users(void)
Free the users structure.
static int vm_intro_no(struct ast_channel *chan, struct vm_state *vms)
char * strsep(char **str, const char *delims)
char * mkdtemp(char *template_s)
char * strcasestr(const char *, const char *)
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_realloc(p, len)
A wrapper for realloc()
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
void ao2_container_unregister(const char *name)
Unregister a container for CLI stats and integrity check.
#define AO2_STRING_FIELD_CMP_FN(stype, field)
Creates a compare function for a structure string field.
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
int ao2_container_register(const char *name, struct ao2_container *self, ao2_prnt_obj_fn *prnt_obj)
Register a container for CLI stats and integrity check.
#define AO2_STRING_FIELD_HASH_FN(stype, field)
Creates a hash function for a structure string field.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
#define ao2_alloc(data_size, destructor_fn)
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
void() ao2_prnt_fn(void *where, const char *fmt,...)
Print output.
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
static SQLHSTMT generic_prepare(struct odbc_obj *obj, void *data)
static char language[MAX_LANGUAGE]
static int transfer(void *data)
General Asterisk PBX channel definitions.
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
const char * ast_channel_name(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
#define ast_channel_lock(chan)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define ast_channel_unref(c)
Decrease channel reference count.
const char * ast_channel_language(const struct ast_channel *chan)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
#define ast_dummy_channel_alloc()
Create a fake channel structure.
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_priority_set(struct ast_channel *chan, int value)
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
int ast_answer(struct ast_channel *chan)
Answer a channel.
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
#define AST_MAX_EXTENSION
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
ast_channel_state
ast_channel states
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
Standard Command Line Interface.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
static struct progalias aliases[]
Convenient Signal Processing routines.
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
static char * config_filename
Generic File Format Support. Should be included by clients of the file handling routines....
off_t ast_tellstream(struct ast_filestream *fs)
Tell where we are in a stream.
int ast_stopstream(struct ast_channel *c)
Stops a stream.
int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence)
Seeks into stream.
int ast_filerename(const char *oldname, const char *newname, const char *fmt)
Renames a file.
struct ast_filestream * ast_readfile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
Starts reading from a file.
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
FILE * ast_file_mkftemp(char *template_name, mode_t mode)
same as mkstemp, but return a FILE
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.
char * ast_format_str_reduce(char *fmts)
int ast_filecopy(const char *oldname, const char *newname, const char *fmt)
Copies a file.
int ast_ratestream(struct ast_filestream *fs)
Return the sample rate of the stream's format.
int ast_closestream(struct ast_filestream *f)
Closes a stream.
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
static int exists(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
void ast_manager_publish_event(const char *type, int class_type, struct ast_json *obj)
Publish an event to AMI.
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
void astman_append(struct mansession *s, const char *fmt,...)
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
#define SCOPE_EXIT_RTN(...)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
#define SCOPE_ENTER(level,...)
#define SCOPE_CALL_WITH_INT_RESULT(level, __funcname,...)
#define SCOPE_CALL(level, __funcname,...)
#define SCOPE_EXIT_LOG_RTN(__log_level,...)
#define ast_trace(level,...)
static char prefix[MAX_PREFIX]
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
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 beep, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
Record a file based on input from a channel This function will play "auth-thankyou" upon successful r...
int ast_app_messagecount(const char *mailbox_id, const char *folder)
Get the number of messages in a given mailbox folder.
int ast_control_streamfile(struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *pause, const char *restart, int skipms, long *offsetms)
Stream a file with fast forward, pause, reverse, restart.
void ast_vm_greeter_unregister(const char *module_name)
Unregister the specified voicemail greeter provider.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
enum ast_getdata_result ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout)
Plays a stream and gets DTMF data from a channel.
@ AST_VM_SNAPSHOT_SORT_BY_ID
@ AST_VM_SNAPSHOT_SORT_BY_TIME
int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime_sec, char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence_ms)
Record a file based on input frm a channel. Recording is performed in 'prepend' mode which works a li...
enum AST_LOCK_RESULT ast_lock_path(const char *path)
Lock a filesystem path.
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
int ast_app_has_voicemail(const char *mailboxes, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX"....
#define VM_GREETER_MODULE_VERSION
int ast_safe_fork(int stop_reaper)
Common routine to safely fork without a chance of a signal handler firing badly in the child.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define VM_MODULE_VERSION
struct ast_vm_mailbox_snapshot * ast_vm_mailbox_snapshot_destroy(struct ast_vm_mailbox_snapshot *mailbox_snapshot)
destroy a snapshot
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
void ast_vm_unregister(const char *module_name)
Unregister the specified voicemail provider.
#define ast_vm_register(vm_table)
See __ast_vm_register()
int ast_app_inboxcount(const char *mailboxes, int *newmsgs, int *oldmsgs)
Determine number of new/old messages in a mailbox.
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.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
void() ast_vm_msg_play_cb(struct ast_channel *chan, const char *playfile, int duration)
Voicemail playback callback function definition.
@ AST_RECORD_IF_EXISTS_OVERWRITE
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
int ast_app_inboxcount2(const char *mailboxes, int *urgentmsgs, int *newmsgs, int *oldmsgs)
Determine number of urgent/new/old messages in a mailbox.
#define ast_vm_greeter_register(vm_table)
See __ast_vm_greeter_register()
struct ast_vm_mailbox_snapshot * ast_vm_mailbox_snapshot_create(const char *mailbox, const char *context, const char *folder, int descending, enum ast_vm_snapshot_sort_val sort_val, int combine_INBOX_and_OLD)
Create a snapshot of a mailbox which contains information about every msg.
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.
int ast_unlock_path(const char *path)
Unlock a path.
void ast_close_fds_above_n(int n)
Common routine for child processes, to close all fds prior to exec(2)
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
int ast_update2_realtime(const char *family,...) attribute_sentinel
Update realtime configuration.
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
int ast_config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator)
Save a config text file preserving the pre 13.2 behavior.
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
int ast_variable_update(struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object)
Update variable value within a config.
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category.
#define ast_variable_new(name, value, filename)
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
int ast_destroy_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Destroy realtime configuration.
void ast_category_destroy(struct ast_category *cat)
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
@ CONFIG_FLAG_WITHCOMMENTS
@ CONFIG_FLAG_FILEUNCHANGED
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
int ast_store_realtime(const char *family,...) attribute_sentinel
Create realtime configuration.
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name, const char *filter)
Retrieve a category if it exists.
#define AST_OPTION_RXGAIN
struct ast_frame ast_null_frame
Support for logging to various files, console and syslog Configuration in file logger....
#define DEBUG_ATLEAST(level)
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_HEAD_NOLOCK_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
#define AST_LIST_LOCK(head)
Locks a list.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Custom localtime functions for multiple timezones.
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_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...
int ast_strftime_locale(char *buf, size_t len, const char *format, const struct ast_tm *tm, const char *locale)
Asterisk locking-related definitions:
#define AST_PTHREADT_NULL
#define ast_cond_timedwait(cond, mutex, time)
#define ast_mutex_init(pmutex)
#define ast_mutex_unlock(a)
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
pthread_cond_t ast_cond_t
#define ast_mutex_destroy(a)
#define ast_mutex_lock(a)
#define AST_MUTEX_DEFINE_STATIC(mutex)
#define ast_cond_signal(cond)
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define EVENT_FLAG_REPORTING
#define EVENT_FLAG_SYSTEM
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
int ast_unregister_application(const char *app)
Unregister an application.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
#define ast_publish_mwi_state_channel(mailbox, context, new_msgs, old_msgs, channel_id)
Publish a MWI state update associated with some channel.
void ast_mwi_state_callback_all(on_mwi_state handler, void *data)
For each managed mailbox call the given handler.
void ast_mwi_state_callback_subscribed(on_mwi_state handler, void *data)
For each managed mailbox that has a subscriber call the given handler.
int ast_mwi_add_observer(struct ast_mwi_observer *observer)
Add an observer to receive MWI state related events.
int ast_delete_mwi_state_full(const char *mailbox, const char *context, struct ast_eid *eid)
Delete MWI state cached by stasis with all parameters.
void ast_mwi_remove_observer(struct ast_mwi_observer *observer)
Remove an MWI state observer.
struct ast_mwi_state * ast_mwi_subscriber_data(struct ast_mwi_subscriber *sub)
Retrieves the state data object associated with the MWI subscriber.
Asterisk file paths, configured in asterisk.conf.
const char * ast_config_AST_DATA_DIR
const char * ast_config_AST_SPOOL_DIR
Core PBX routines and definitions.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
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 ast_custom_function_register(acf)
Register a custom function.
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
struct ast_app * pbx_findapp(const char *app)
Look up an application.
static void check_password(void)
static char intro[ADSI_MAX_INTRO][20]
static struct stasis_rest_handlers mailboxes
REST handler for /api-docs/mailboxes.json.
static struct stasis_subscription * sub
Statsd channel stats. Exmaple of how to subscribe to Stasis events.
int ast_odbc_prepare(struct odbc_obj *obj, SQLHSTMT *stmt, const char *sql)
Prepares a SQL query on a statement.
void ast_odbc_release_obj(struct odbc_obj *obj)
Releases an ODBC object previously allocated by ast_odbc_request_obj()
struct ast_str * ast_odbc_print_errors(SQLSMALLINT handle_type, SQLHANDLE handle, const char *operation)
Shortcut for printing errors to logs after a failed SQL operation.
SQLHSTMT ast_odbc_direct_execute(struct odbc_obj *obj, SQLHSTMT(*exec_cb)(struct odbc_obj *obj, void *data), void *data)
Executes an non prepared statement and returns the resulting statement handle.
SQLRETURN ast_odbc_execute_sql(struct odbc_obj *obj, SQLHSTMT *stmt, const char *sql)
Execute a unprepared SQL query.
SQLHSTMT ast_odbc_prepare_and_execute(struct odbc_obj *obj, SQLHSTMT(*prepare_cb)(struct odbc_obj *obj, void *data), void *data)
Prepares, executes, and returns the resulting statement handle.
#define ast_odbc_request_obj(name, check)
Get a ODBC connection object.
static int load_users(void)
static void cleanup(void)
Clean up any old apps that we don't need any more.
static int debug
Global debug status.
Say numbers and dates (maybe words one day too)
int ast_say_character_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity)
function to pronounce character and phonetic strings
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
SAY_EXTERN int(* ast_say_date_with_format)(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezone) SAY_INIT(ast_say_date_with_format)
int ast_say_counted_noun(struct ast_channel *chan, int num, const char *noun)
int ast_say_counted_adjective(struct ast_channel *chan, int num, const char *adjective, const char *gender)
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
SMDI support for Asterisk.
int AST_OPTIONAL_API_NAME() ast_smdi_mwi_unset(struct ast_smdi_interface *iface, const char *mailbox)
Unset the MWI indicator for a mailbox.
int AST_OPTIONAL_API_NAME() ast_smdi_mwi_set(struct ast_smdi_interface *iface, const char *mailbox)
Set the MWI indicator for a mailbox.
struct ast_smdi_interface *AST_OPTIONAL_API_NAME() ast_smdi_interface_find(const char *iface_name)
Find an SMDI interface with the specified name.
struct ast_smdi_mwi_message *AST_OPTIONAL_API_NAME() ast_smdi_mwi_message_wait_station(struct ast_smdi_interface *iface, int timeout, const char *station)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
String manipulation functions.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
size_t attribute_pure ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
Parse a time (integer) string.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
int ast_build_string(char **buffer, size_t *space, const char *fmt,...)
Build a string in a buffer, designed to be called repeatedly.
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
#define ast_str_alloca(init_len)
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
ast_app: A registered application
struct ast_app::@409 list
Structure to describe a channel "technology", ie a channel driver See for examples:
int(*const write)(struct ast_channel *chan, struct ast_frame *frame)
Write a frame, in standard format (see frame.h)
struct ast_format_cap * capabilities
Main Channel structure associated with a channel.
char context[AST_MAX_CONTEXT]
descriptor for a cli entry.
Data structure associated with a custom dialplan function.
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Structure used to handle boolean flags.
Data structure associated with a single frame of data.
Abstract JSON element (object, array, string, int, ...).
Structure for mutex and tracking information.
MWI state event interface.
void(* on_subscribe)(const char *mailbox, struct ast_mwi_subscriber *sub)
Raised when MWI is being subscribed.
The structure that contains MWI state.
const ast_string_field uniqueid
Caller Party information.
struct ast_party_id id
Caller party ID.
struct ast_party_name name
Subscriber name.
struct ast_party_number number
Subscriber phone number.
unsigned char valid
TRUE if the name information is valid/present.
char * str
Subscriber name (Malloced)
unsigned char valid
TRUE if the number information is valid/present.
char * str
Subscriber phone number (Malloced)
An SMDI message waiting indicator message.
char cause[SMDI_MWI_FAIL_CAUSE_LEN+1]
char fwd_st[SMDI_MAX_STATION_NUM_LEN+1]
Support for dynamic strings.
A ast_taskprocessor structure is a singleton by name.
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
Voicemail function table definition.
unsigned int module_version
The version of this function table.
const char * module_name
The name of the module that provides the voicemail functionality.
Voicemail greeter function table definition.
unsigned int module_version
The version of this function table.
const char * module_name
The name of the module that provides the voicemail greeter functionality.
struct ast_vm_mailbox_snapshot::@196 * snapshots
struct ast_vm_msg_snapshot::@195 msg
const ast_string_field origtime
const ast_string_field msg_id
Structure used for ast_copy_recording_to_vm in order to cleanly supply data needed for making the rec...
const ast_string_field recording_file
const ast_string_field call_callerchan
const ast_string_field context
const ast_string_field folder
const ast_string_field call_callerid
const ast_string_field call_context
const ast_string_field recording_ext
const ast_string_field call_extension
const ast_string_field mailbox
char context[MAX_VM_CONTEXT_LEN]
char mailbox[MAX_VM_MBOX_ID_LEN]
struct ast_vm_user::@86 list
char language[MAX_LANGUAGE]
All configuration options for http media cache.
structure to hold extensions
Options for leaving voicemail with the voicemail() application.
In case you didn't read that giant block of text above the mansession_session struct,...
structure to hold users read from phoneprov_users.conf
list of users found in the config file
An API for managing task processing threads that can be shared across modules.
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary.
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
#define AST_TASKPROCESSOR_HIGH_WATER_LEVEL
int ast_taskprocessor_alert_set_levels(struct ast_taskprocessor *tps, long low_water, long high_water)
Set the high and low alert water marks of the given taskprocessor queue.
#define AST_TEST_REGISTER(cb)
#define ast_test_status_update(a, b, c...)
#define AST_TEST_UNREGISTER(cb)
#define ast_test_suite_event_notify(s, f,...)
#define AST_TEST_DEFINE(hdr)
Definitions to aid in the use of thread local storage.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Time-related functions and macros.
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define ast_test_flag(p, flag)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
int ast_file_is_readable(const char *filename)
Test that a file exists and is readable by the effective user.
#define ast_pthread_create(a, b, c, d)
#define ast_set2_flag(p, value, flag)
#define ast_clear_flag(p, flag)
long int ast_random(void)
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
#define ast_set_flag(p, flag)
#define ast_copy_flags(dest, src, flagz)
int ast_base64_encode_file_path(const char *filename, FILE *outputfile, const char *endl)
Performs a base 64 encode algorithm on the contents of a File.