Sat Apr 12 07:12:32 2008

Asterisk developer's documentation


app_voicemail.c File Reference

Comedian Mail - Voicemail System. More...

#include "asterisk.h"
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/module.h"
#include "asterisk/adsi.h"
#include "asterisk/app.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/stringfields.h"
#include "asterisk/smdi.h"

Include dependency graph for app_voicemail.c:

Go to the source code of this file.

Data Structures

struct  ast_vm_user
struct  baseio
struct  leave_vm_options
struct  vm_state
struct  vm_zone

Defines

#define ASTERISK_USERNAME   "asterisk"
#define BASELINELEN   72
#define BASEMAXINLINE   256
#define BASEMAXINLINE   256
#define CHUNKSIZE   65536
#define COMMAND_TIMEOUT   5000
#define COPY(a, b, c, d, e, f, g, h)   (copy_file(g,h));
#define DELETE(a, b, c)   (vm_delete(c))
#define DISPOSE(a, b)
#define ENDL   "\n"
#define eol   "\r\n"
#define ERROR_LOCK_PATH   -100
#define EXISTS(a, b, c, d)   (ast_fileexists(c,NULL,d) > 0)
#define INTRO   "vm-intro"
#define MAX_DATETIME_FORMAT   512
#define MAX_NUM_CID_CONTEXTS   10
#define MAXMSG   100
#define MAXMSGLIMIT   9999
#define RENAME(a, b, c, d, e, f, g, h)   (rename_file(g,h));
#define RETRIEVE(a, b)
#define SENDMAIL   "/usr/sbin/sendmail -t"
#define SMDI_MWI_WAIT_TIMEOUT   1000
#define STORE(a, b, c, d, e, f, g, h, i)
#define tdesc   "Comedian Mail (Voicemail System)"
#define VM_ALLOCED   (1 << 13)
#define VM_ATTACH   (1 << 11)
#define VM_DELETE   (1 << 12)
#define VM_DIRECFORWARD   (1 << 10)
#define VM_ENVELOPE   (1 << 4)
#define VM_FORCEGREET   (1 << 8)
#define VM_FORCENAME   (1 << 7)
#define VM_OPERATOR   (1 << 1)
#define VM_PBXSKIP   (1 << 9)
#define VM_REVIEW   (1 << 0)
#define VM_SAYCID   (1 << 2)
#define VM_SAYDURATION   (1 << 5)
#define VM_SEARCH   (1 << 14)
#define VM_SKIPAFTERCMD   (1 << 6)
#define VM_SVMAIL   (1 << 3)
#define VM_TEMPGREETWARN   (1 << 15)
#define VOICEMAIL_CONFIG   "voicemail.conf"
#define VOICEMAIL_DIR_MODE   0777
#define VOICEMAIL_FILE_MODE   0666

Enumerations

enum  {
  OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3),
  OPT_PREPEND_MAILBOX = (1 << 4), OPT_PRIORITY_JUMP = (1 << 5), OPT_AUTOPLAY = (1 << 6)
}
enum  { OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_ARRAY_SIZE = 2 }

Functions

static int __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit)
static void adsi_begin (struct ast_channel *chan, int *useadsi)
static void adsi_delete (struct ast_channel *chan, struct vm_state *vms)
static void adsi_folders (struct ast_channel *chan, int start, char *label)
static void adsi_goodbye (struct ast_channel *chan)
static int adsi_load_vmail (struct ast_channel *chan, int *useadsi)
static void adsi_login (struct ast_channel *chan)
static int adsi_logo (unsigned char *buf)
static void adsi_message (struct ast_channel *chan, struct vm_state *vms)
static void adsi_password (struct ast_channel *chan)
static void adsi_status (struct ast_channel *chan, struct vm_state *vms)
static void adsi_status2 (struct ast_channel *chan, struct vm_state *vms)
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)
static int append_mailbox (char *context, char *mbox, char *data)
static void apply_option (struct ast_vm_user *vmu, const char *var, const char *value)
static void apply_options (struct ast_vm_user *vmu, const char *options)
static void apply_options_full (struct ast_vm_user *retval, struct ast_variable *var)
 AST_APP_OPTIONS (vm_app_options,{AST_APP_OPTION('s', OPT_SILENT), AST_APP_OPTION('b', OPT_BUSY_GREETING), AST_APP_OPTION('u', OPT_UNAVAIL_GREETING), AST_APP_OPTION_ARG('g', OPT_RECORDGAIN, OPT_ARG_RECORDGAIN), AST_APP_OPTION('p', OPT_PREPEND_MAILBOX), AST_APP_OPTION('j', OPT_PRIORITY_JUMP), AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER),})
static AST_LIST_HEAD_STATIC (zones, vm_zone)
static AST_LIST_HEAD_STATIC (users, ast_vm_user)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,.load=load_module,.unload=unload_module,.reload=reload,)
static int base_encode (char *filename, FILE *so)
static int change_password_realtime (struct ast_vm_user *vmu, const char *password)
static int close_mailbox (struct vm_state *vms, struct ast_vm_user *vmu)
static char * complete_voicemail_show_users (const char *line, const char *word, int pos, int state)
static int copy (char *infile, char *outfile)
static void copy_file (char *frompath, char *topath)
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)
static int count_messages (struct ast_vm_user *vmu, char *dir)
static int create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder)
 basically mkdir -p $dest/$context/$ext/$folder
static int dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
static struct ast_vm_userfind_or_create (char *context, char *mbox)
static struct ast_vm_userfind_user (struct ast_vm_user *ivm, const char *context, const char *mailbox)
static struct ast_vm_userfind_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox)
static int forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int flag, signed char record_gain)
static void free_user (struct ast_vm_user *vmu)
static void free_zone (struct vm_zone *z)
static int get_date (char *s, int len)
static int get_folder (struct ast_channel *chan, int start)
static int get_folder2 (struct ast_channel *chan, char *fn, int start)
static int get_lastdigits (int num)
static int handle_voicemail_show_users (int fd, int argc, char *argv[])
static int handle_voicemail_show_zones (int fd, int argc, char *argv[])
static int has_voicemail (const char *mailbox, const char *folder)
static int inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs)
static int inbuf (struct baseio *bio, FILE *fi)
static int inchar (struct baseio *bio, FILE *fi)
static int invent_message (struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes)
static int last_message_index (struct ast_vm_user *vmu, char *dir)
static int leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options)
static int load_config (void)
static int load_module (void)
static int make_dir (char *dest, int len, const char *context, const char *ext, const char *folder)
static void make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap)
static int make_file (char *dest, int len, char *dir, int num)
static const char * mbox (int id)
static int messagecount (const char *context, const char *mailbox, const char *folder)
static int notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
static int ochar (struct baseio *bio, int c, FILE *so)
static int open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box)
static int play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback)
static int play_message_category (struct ast_channel *chan, const char *category)
static int play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename)
static int play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration)
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, const char *unlockdir, signed char record_gain, struct vm_state *vms)
static void populate_defaults (struct ast_vm_user *vmu)
static void prep_email_sub_vars (struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *dur, char *date, char *passdata, size_t passdatasize, const char *category)
static char * quote (const char *from, char *to, size_t len)
static int reload (void)
static void rename_file (char *sfn, char *dfn)
static int resequence_mailbox (struct ast_vm_user *vmu, char *dir)
static int reset_user_pw (const char *context, const char *mailbox, const char *newpass)
static void run_externnotify (char *context, char *extension)
static int save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box)
static int say_and_wait (struct ast_channel *chan, int num, const char *language)
static int sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category)
static int sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category)
static int unload_module (void)
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 maxlogins, int silent)
static int vm_box_exists (struct ast_channel *chan, void *data)
static int vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static void vm_change_password (struct ast_vm_user *vmu, const char *newpassword)
static void vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword)
static int vm_delete (char *file)
static int vm_exec (struct ast_channel *chan, void *data)
static int vm_execmain (struct ast_channel *chan, void *data)
static int vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vmfmts, char *context, signed char record_gain, long *duration, struct vm_state *vms)
static int vm_instructions (struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
static int vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int vm_intro_cz (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_de (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_en (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_es (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_fr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_gr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_it (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_nl (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_no (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pl (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pt (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_ru (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_se (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_ua (struct ast_channel *chan, struct vm_state *vms)
static int vm_lock_path (const char *path)
static FILE * vm_mkftemp (char *template)
static int vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int vm_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int vm_play_folder_name (struct ast_channel *chan, char *mbox)
static int vm_play_folder_name_gr (struct ast_channel *chan, char *mbox)
static int vm_play_folder_name_pl (struct ast_channel *chan, char *mbox)
static int vm_play_folder_name_ua (struct ast_channel *chan, char *mbox)
static int vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int vmauthenticate (struct ast_channel *chan, void *data)
static struct tm * vmu_tm (const struct ast_vm_user *vmu, struct tm *tm)
static int wait_file (struct ast_channel *chan, struct vm_state *vms, char *file)
static int wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file)

Variables

static char * addesc = "Comedian Mail"
static unsigned char adsifdn [4] = "\x00\x00\x00\x0F"
static unsigned char adsisec [4] = "\x9B\xDB\xF7\xAC"
static int adsiver = 1
static char * app = "VoiceMail"
static char * app2 = "VoiceMailMain"
static char * app3 = "MailboxExists"
static char * app4 = "VMAuthenticate"
static char callcontext [AST_MAX_CONTEXT]
static char charset [32] = "ISO-8859-1"
static char cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64]
static struct ast_cli_entry cli_show_voicemail_users_deprecated
static struct ast_cli_entry cli_show_voicemail_zones_deprecated
static struct ast_cli_entry cli_voicemail []
static char * descrip_vm
static char * descrip_vm_box_exists
static char * descrip_vmain
static char * descrip_vmauthenticate
static char dialcontext [AST_MAX_CONTEXT]
static char * emailbody = NULL
static char emaildateformat [32] = "%A, %B %d, %Y at %r"
static char * emailsubject = NULL
static char emailtitle [100]
static char exitcontext [AST_MAX_CONTEXT]
static char ext_pass_cmd [128]
static char externnotify [160]
static char fromstring [100]
static struct ast_flags globalflags = {0}
static char mailcmd [160]
static int maxgreet
static int maxlogins
static int maxmsg
static int maxsilence
int my_umask
static char * pagerbody = NULL
static char pagerfromstring [100]
static char * pagersubject = NULL
static int saydurationminfo
static char serveremail [80]
static int silencethreshold = 128
static int skipms
static struct ast_smdi_interfacesmdi_iface = NULL
static char * synopsis_vm
static char * synopsis_vm_box_exists
static char * synopsis_vmain
static char * synopsis_vmauthenticate
static char userscontext [AST_MAX_EXTENSION] = "default"
enum { ... }  vm_option_args
enum { ... }  vm_option_flags
static char VM_SPOOL_DIR [PATH_MAX]
static char vmfmts [80]
static int vmmaxmessage
static int vmminmessage
static char voicemail_show_users_help []
static char voicemail_show_zones_help []
static double volgain


Detailed Description

Comedian Mail - Voicemail System.

Author:
Mark Spencer <markster@digium.com>
See also
Note:
This module requires res_adsi to load.

Definition in file app_voicemail.c.


Define Documentation

#define ASTERISK_USERNAME   "asterisk"

Definition at line 155 of file app_voicemail.c.

Referenced by load_config().

#define BASELINELEN   72

Definition at line 171 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 172 of file app_voicemail.c.

#define BASEMAXINLINE   256

Definition at line 172 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 152 of file app_voicemail.c.

#define COMMAND_TIMEOUT   5000

Definition at line 148 of file app_voicemail.c.

#define COPY ( a,
b,
c,
d,
e,
f,
g,
 )     (copy_file(g,h));

Definition at line 415 of file app_voicemail.c.

Referenced by copy_message(), and save_to_folder().

#define DELETE ( a,
b,
 )     (vm_delete(c))

#define DISPOSE ( a,
 ) 

#define ENDL   "\n"

Referenced by make_email_file().

#define eol   "\r\n"

Definition at line 173 of file app_voicemail.c.

Referenced by base_encode(), and ochar().

#define ERROR_LOCK_PATH   -100

#define EXISTS ( a,
b,
c,
 )     (ast_fileexists(c,NULL,d) > 0)

#define INTRO   "vm-intro"

Definition at line 161 of file app_voicemail.c.

Referenced by leave_voicemail(), and play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 175 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 176 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 163 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

Definition at line 165 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define RENAME ( a,
b,
c,
d,
e,
f,
g,
 )     (rename_file(g,h));

Definition at line 414 of file app_voicemail.c.

Referenced by close_mailbox(), and resequence_mailbox().

#define RETRIEVE ( a,
 ) 

#define SENDMAIL   "/usr/sbin/sendmail -t"

Definition at line 159 of file app_voicemail.c.

Referenced by load_config().

#define SMDI_MWI_WAIT_TIMEOUT   1000

Definition at line 146 of file app_voicemail.c.

Referenced by run_externnotify().

#define STORE ( a,
b,
c,
d,
e,
f,
g,
h,
 ) 

#define tdesc   "Comedian Mail (Voicemail System)"

Definition at line 431 of file app_voicemail.c.

#define VM_ALLOCED   (1 << 13)

Definition at line 191 of file app_voicemail.c.

Referenced by find_user(), find_user_realtime(), free_user(), and load_config().

#define VM_ATTACH   (1 << 11)

#define VM_DELETE   (1 << 12)

Definition at line 190 of file app_voicemail.c.

Referenced by apply_option(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 188 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

Definition at line 182 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and play_message().

#define VM_FORCEGREET   (1 << 8)

Have new users record their greetings

Definition at line 186 of file app_voicemail.c.

Referenced by apply_option(), load_config(), vm_execmain(), and vm_newuser().

#define VM_FORCENAME   (1 << 7)

Have new users record their name

Definition at line 185 of file app_voicemail.c.

Referenced by apply_option(), load_config(), vm_execmain(), and vm_newuser().

#define VM_OPERATOR   (1 << 1)

Definition at line 179 of file app_voicemail.c.

Referenced by apply_option(), leave_voicemail(), load_config(), and play_record_review().

#define VM_PBXSKIP   (1 << 9)

Definition at line 187 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

#define VM_REVIEW   (1 << 0)

Definition at line 178 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and play_record_review().

#define VM_SAYCID   (1 << 2)

Definition at line 180 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and play_message().

#define VM_SAYDURATION   (1 << 5)

Definition at line 183 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and play_message().

#define VM_SEARCH   (1 << 14)

Definition at line 192 of file app_voicemail.c.

Referenced by find_or_create(), find_user(), find_user_realtime(), and load_config().

#define VM_SKIPAFTERCMD   (1 << 6)

Definition at line 184 of file app_voicemail.c.

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

Definition at line 181 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and vm_execmain().

#define VM_TEMPGREETWARN   (1 << 15)

Remind user tempgreeting is set

Definition at line 193 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and vm_intro().

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 154 of file app_voicemail.c.

#define VOICEMAIL_DIR_MODE   0777

Definition at line 150 of file app_voicemail.c.

Referenced by create_dirpath().

#define VOICEMAIL_FILE_MODE   0666

Definition at line 151 of file app_voicemail.c.

Referenced by copy(), leave_voicemail(), make_email_file(), and vm_mkftemp().


Enumeration Type Documentation

anonymous enum

Enumerator:
OPT_SILENT 
OPT_BUSY_GREETING 
OPT_UNAVAIL_GREETING 
OPT_RECORDGAIN 
OPT_PREPEND_MAILBOX 
OPT_PRIORITY_JUMP 
OPT_AUTOPLAY 

Definition at line 197 of file app_voicemail.c.

00197      {
00198    OPT_SILENT =           (1 << 0),
00199    OPT_BUSY_GREETING =    (1 << 1),
00200    OPT_UNAVAIL_GREETING = (1 << 2),
00201    OPT_RECORDGAIN =       (1 << 3),
00202    OPT_PREPEND_MAILBOX =  (1 << 4),
00203    OPT_PRIORITY_JUMP =    (1 << 5),
00204    OPT_AUTOPLAY =         (1 << 6),
00205 } vm_option_flags;

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_ARRAY_SIZE 

Definition at line 207 of file app_voicemail.c.

00207      {
00208    OPT_ARG_RECORDGAIN = 0,
00209    OPT_ARG_PLAYFOLDER = 1,
00210    /* This *must* be the last value in this enum! */
00211    OPT_ARG_ARRAY_SIZE = 2,
00212 } vm_option_args;


Function Documentation

static int __has_voicemail ( const char *  context,
const char *  mailbox,
const char *  folder,
int  shortcircuit 
) [static]

Definition at line 2635 of file app_voicemail.c.

References ast_strlen_zero(), and VM_SPOOL_DIR.

Referenced by has_voicemail(), inboxcount(), and messagecount().

02636 {
02637    DIR *dir;
02638    struct dirent *de;
02639    char fn[256];
02640    int ret = 0;
02641    if (!folder)
02642       folder = "INBOX";
02643    /* If no mailbox, return immediately */
02644    if (ast_strlen_zero(mailbox))
02645       return 0;
02646    if (!context)
02647       context = "default";
02648    snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
02649    dir = opendir(fn);
02650    if (!dir)
02651       return 0;
02652    while ((de = readdir(dir))) {
02653       if (!strncasecmp(de->d_name, "msg", 3)) {
02654          if (shortcircuit) {
02655             ret = 1;
02656             break;
02657          } else if (!strncasecmp(de->d_name + 8, "txt", 3))
02658             ret++;
02659       }
02660    }
02661    closedir(dir);
02662    return ret;
02663 }

static void adsi_begin ( struct ast_channel chan,
int *  useadsi 
) [static]

Definition at line 3415 of file app_voicemail.c.

References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available(), ast_adsi_load_session(), ast_log(), and LOG_WARNING.

Referenced by vm_authenticate(), and vm_execmain().

03416 {
03417    int x;
03418    if (!ast_adsi_available(chan))
03419       return;
03420    x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
03421    if (x < 0)
03422       return;
03423    if (!x) {
03424       if (adsi_load_vmail(chan, useadsi)) {
03425          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
03426          return;
03427       }
03428    } else
03429       *useadsi = 1;
03430 }

static void adsi_delete ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 3602 of file app_voicemail.c.

References ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_set_keys(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), vm_state::curmsg, vm_state::deleted, keys, and vm_state::lastmsg.

Referenced by vm_execmain().

03603 {
03604    int bytes=0;
03605    unsigned char buf[256];
03606    unsigned char keys[8];
03607 
03608    int x;
03609 
03610    if (!ast_adsi_available(chan))
03611       return;
03612 
03613    /* New meaning for keys */
03614    for (x=0;x<5;x++)
03615       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
03616 
03617    keys[6] = 0x0;
03618    keys[7] = 0x0;
03619 
03620    if (!vms->curmsg) {
03621       /* No prev key, provide "Folder" instead */
03622       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03623    }
03624    if (vms->curmsg >= vms->lastmsg) {
03625       /* If last message ... */
03626       if (vms->curmsg) {
03627          /* but not only message, provide "Folder" instead */
03628          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03629       } else {
03630          /* Otherwise if only message, leave blank */
03631          keys[3] = 1;
03632       }
03633    }
03634 
03635    /* If deleted, show "undeleted" */
03636    if (vms->deleted[vms->curmsg]) 
03637       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
03638 
03639    /* Except "Exit" */
03640    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
03641    bytes += ast_adsi_set_keys(buf + bytes, keys);
03642    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03643 
03644    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03645 }

static void adsi_folders ( struct ast_channel chan,
int  start,
char *  label 
) [static]

Definition at line 3480 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), and keys.

Referenced by vm_execmain().

03481 {
03482    unsigned char buf[256];
03483    int bytes=0;
03484    unsigned char keys[8];
03485    int x,y;
03486 
03487    if (!ast_adsi_available(chan))
03488       return;
03489 
03490    for (x=0;x<5;x++) {
03491       y = ADSI_KEY_APPS + 12 + start + x;
03492       if (y > ADSI_KEY_APPS + 12 + 4)
03493          y = 0;
03494       keys[x] = ADSI_KEY_SKT | y;
03495    }
03496    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
03497    keys[6] = 0;
03498    keys[7] = 0;
03499 
03500    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
03501    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
03502    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03503    bytes += ast_adsi_set_keys(buf + bytes, keys);
03504    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03505 
03506    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03507 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

Definition at line 3750 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), and ast_adsi_voice_mode().

Referenced by vm_execmain().

03751 {
03752    unsigned char buf[256];
03753    int bytes=0;
03754 
03755    if (!ast_adsi_available(chan))
03756       return;
03757    bytes += adsi_logo(buf + bytes);
03758    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
03759    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
03760    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03761    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03762 
03763    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03764 }

static int adsi_load_vmail ( struct ast_channel chan,
int *  useadsi 
) [static]

Definition at line 3284 of file app_voicemail.c.

References addesc, ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, adsifdn, adsisec, adsiver, ast_adsi_begin_download(), ast_adsi_data_mode(), ast_adsi_display(), ast_adsi_download_disconnect(), ast_adsi_end_download(), ast_adsi_load_session(), ast_adsi_load_soft_key(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_log(), LOG_DEBUG, mbox(), and option_debug.

Referenced by adsi_begin().

03285 {
03286    unsigned char buf[256];
03287    int bytes=0;
03288    int x;
03289    char num[5];
03290 
03291    *useadsi = 0;
03292    bytes += ast_adsi_data_mode(buf + bytes);
03293    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03294 
03295    bytes = 0;
03296    bytes += adsi_logo(buf);
03297    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
03298 #ifdef DISPLAY
03299    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
03300 #endif
03301    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03302    bytes += ast_adsi_data_mode(buf + bytes);
03303    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03304 
03305    if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
03306       bytes = 0;
03307       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
03308       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
03309       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03310       bytes += ast_adsi_voice_mode(buf + bytes, 0);
03311       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03312       return 0;
03313    }
03314 
03315 #ifdef DISPLAY
03316    /* Add a dot */
03317    bytes = 0;
03318    bytes += ast_adsi_logo(buf);
03319    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
03320    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
03321    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03322    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03323 #endif
03324    bytes = 0;
03325    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
03326    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
03327    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
03328    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
03329    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
03330    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
03331    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03332 
03333 #ifdef DISPLAY
03334    /* Add another dot */
03335    bytes = 0;
03336    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
03337    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03338 
03339    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03340    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03341 #endif
03342 
03343    bytes = 0;
03344    /* These buttons we load but don't use yet */
03345    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
03346    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
03347    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
03348    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
03349    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
03350    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
03351    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03352 
03353 #ifdef DISPLAY
03354    /* Add another dot */
03355    bytes = 0;
03356    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
03357    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03358    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03359 #endif
03360 
03361    bytes = 0;
03362    for (x=0;x<5;x++) {
03363       snprintf(num, sizeof(num), "%d", x);
03364       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
03365    }
03366    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
03367    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03368 
03369 #ifdef DISPLAY
03370    /* Add another dot */
03371    bytes = 0;
03372    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
03373    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03374    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03375 #endif
03376 
03377    if (ast_adsi_end_download(chan)) {
03378       bytes = 0;
03379       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
03380       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
03381       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03382       bytes += ast_adsi_voice_mode(buf + bytes, 0);
03383       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03384       return 0;
03385    }
03386    bytes = 0;
03387    bytes += ast_adsi_download_disconnect(buf + bytes);
03388    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03389    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03390 
03391    if (option_debug)
03392       ast_log(LOG_DEBUG, "Done downloading scripts...\n");
03393 
03394 #ifdef DISPLAY
03395    /* Add last dot */
03396    bytes = 0;
03397    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
03398    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03399 #endif
03400    if (option_debug)
03401       ast_log(LOG_DEBUG, "Restarting session...\n");
03402 
03403    bytes = 0;
03404    /* Load the session now */
03405    if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
03406       *useadsi = 1;
03407       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
03408    } else
03409       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
03410 
03411    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03412    return 0;
03413 }

static void adsi_login ( struct ast_channel chan  )  [static]

Definition at line 3432 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_input_control(), ast_adsi_input_format(), ast_adsi_load_soft_key(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), and keys.

Referenced by vm_authenticate().

03433 {
03434    unsigned char buf[256];
03435    int bytes=0;
03436    unsigned char keys[8];
03437    int x;
03438    if (!ast_adsi_available(chan))
03439       return;
03440 
03441    for (x=0;x<8;x++)
03442       keys[x] = 0;
03443    /* Set one key for next */
03444    keys[3] = ADSI_KEY_APPS + 3;
03445 
03446    bytes += adsi_logo(buf + bytes);
03447    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
03448    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
03449    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03450    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
03451    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
03452    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
03453    bytes += ast_adsi_set_keys(buf + bytes, keys);
03454    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03455    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03456 }

static int adsi_logo ( unsigned char *  buf  )  [static]

Definition at line 3276 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, and ast_adsi_display().

Referenced by adsi_goodbye(), adsi_load_vmail(), adsi_login(), vm_newuser(), vm_options(), and vm_tempgreeting().

03277 {
03278    int bytes = 0;
03279    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
03280    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
03281    return bytes;
03282 }

static void adsi_message ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 3509 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_callerid_parse(), ast_strlen_zero(), vm_state::curbox, vm_state::curmsg, vm_state::deleted, vm_state::fn, keys, vm_state::lastmsg, name, and strsep().

Referenced by play_message(), and vm_execmain().

03510 {
03511    int bytes=0;
03512    unsigned char buf[256]; 
03513    char buf1[256], buf2[256];
03514    char fn2[PATH_MAX];
03515 
03516    char cid[256]="";
03517    char *val;
03518    char *name, *num;
03519    char datetime[21]="";
03520    FILE *f;
03521 
03522    unsigned char keys[8];
03523 
03524    int x;
03525 
03526    if (!ast_adsi_available(chan))
03527       return;
03528 
03529    /* Retrieve important info */
03530    snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
03531    f = fopen(fn2, "r");
03532    if (f) {
03533       while (!feof(f)) {   
03534          fgets((char *)buf, sizeof(buf), f);
03535          if (!feof(f)) {
03536             char *stringp=NULL;
03537             stringp = (char *)buf;
03538             strsep(&stringp, "=");
03539             val = strsep(&stringp, "=");
03540             if (!ast_strlen_zero(val)) {
03541                if (!strcmp((char *)buf, "callerid"))
03542                   ast_copy_string(cid, val, sizeof(cid));
03543                if (!strcmp((char *)buf, "origdate"))
03544                   ast_copy_string(datetime, val, sizeof(datetime));
03545             }
03546          }
03547       }
03548       fclose(f);
03549    }
03550    /* New meaning for keys */
03551    for (x=0;x<5;x++)
03552       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
03553    keys[6] = 0x0;
03554    keys[7] = 0x0;
03555 
03556    if (!vms->curmsg) {
03557       /* No prev key, provide "Folder" instead */
03558       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03559    }
03560    if (vms->curmsg >= vms->lastmsg) {
03561       /* If last message ... */
03562       if (vms->curmsg) {
03563          /* but not only message, provide "Folder" instead */
03564          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03565          bytes += ast_adsi_voice_mode(buf + bytes, 0);
03566 
03567       } else {
03568          /* Otherwise if only message, leave blank */
03569          keys[3] = 1;
03570       }
03571    }
03572 
03573    if (!ast_strlen_zero(cid)) {
03574       ast_callerid_parse(cid, &name, &num);
03575       if (!name)
03576          name = num;
03577    } else
03578       name = "Unknown Caller";
03579 
03580    /* If deleted, show "undeleted" */
03581 
03582    if (vms->deleted[vms->curmsg])
03583       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
03584 
03585    /* Except "Exit" */
03586    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
03587    snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
03588       strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
03589    snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
03590 
03591    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03592    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03593    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
03594    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
03595    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03596    bytes += ast_adsi_set_keys(buf + bytes, keys);
03597    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03598 
03599    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03600 }

static void adsi_password ( struct ast_channel chan  )  [static]

Definition at line 3458 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_input_control(), ast_adsi_input_format(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), and keys.

Referenced by vm_authenticate().

03459 {
03460    unsigned char buf[256];
03461    int bytes=0;
03462    unsigned char keys[8];
03463    int x;
03464    if (!ast_adsi_available(chan))
03465       return;
03466 
03467    for (x=0;x<8;x++)
03468       keys[x] = 0;
03469    /* Set one key for next */
03470    keys[3] = ADSI_KEY_APPS + 3;
03471 
03472    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03473    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
03474    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
03475    bytes += ast_adsi_set_keys(buf + bytes, keys);
03476    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03477    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03478 }

static void adsi_status ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 3647 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), keys, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_execmain().

03648 {
03649    unsigned char buf[256] = "";
03650    char buf1[256] = "", buf2[256] = "";
03651    int bytes=0;
03652    unsigned char keys[8];
03653    int x;
03654 
03655    char *newm = (vms->newmessages == 1) ? "message" : "messages";
03656    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
03657    if (!ast_adsi_available(chan))
03658       return;
03659    if (vms->newmessages) {
03660       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
03661       if (vms->oldmessages) {
03662          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
03663          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
03664       } else {
03665          snprintf(buf2, sizeof(buf2), "%s.", newm);
03666       }
03667    } else if (vms->oldmessages) {
03668       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
03669       snprintf(buf2, sizeof(buf2), "%s.", oldm);
03670    } else {
03671       strcpy(buf1, "You have no messages.");
03672       buf2[0] = ' ';
03673       buf2[1] = '\0';
03674    }
03675    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03676    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03677    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03678 
03679    for (x=0;x<6;x++)
03680       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03681    keys[6] = 0;
03682    keys[7] = 0;
03683 
03684    /* Don't let them listen if there are none */
03685    if (vms->lastmsg < 0)
03686       keys[0] = 1;
03687    bytes += ast_adsi_set_keys(buf + bytes, keys);
03688 
03689    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03690 
03691    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03692 }

static void adsi_status2 ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 3694 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), vm_state::curbox, keys, and vm_state::lastmsg.

Referenced by vm_execmain().

03695 {
03696    unsigned char buf[256] = "";
03697    char buf1[256] = "", buf2[256] = "";
03698    int bytes=0;
03699    unsigned char keys[8];
03700    int x;
03701 
03702    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
03703 
03704    if (!ast_adsi_available(chan))
03705       return;
03706 
03707    /* Original command keys */
03708    for (x=0;x<6;x++)
03709       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03710 
03711    keys[6] = 0;
03712    keys[7] = 0;
03713 
03714    if ((vms->lastmsg + 1) < 1)
03715       keys[0] = 0;
03716 
03717    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
03718       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
03719 
03720    if (vms->lastmsg + 1)
03721       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
03722    else
03723       strcpy(buf2, "no messages.");
03724    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03725    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03726    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
03727    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03728    bytes += ast_adsi_set_keys(buf + bytes, keys);
03729 
03730    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03731 
03732    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03733    
03734 }

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 
) [static]

Definition at line 7946 of file app_voicemail.c.

References ast_callerid_parse(), ast_config_destroy(), ast_config_load(), ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_variable_retrieve(), ast_verbose(), ast_waitfordigit(), ast_vm_user::callback, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, DISPOSE, find_user(), vm_state::fn, vm_state::fn2, vm_state::heard, leave_voicemail(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, make_file(), name, option_debug, option_verbose, play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, VERBOSE_PREFIX_3, and wait_file().

Referenced by vm_execmain().

07947 {
07948    int res = 0;
07949 #ifdef IMAP_STORAGE
07950    char origtimeS[256],cidS[256],contextS[256];
07951    char *header_content,*temp;
07952 #endif
07953    char filename[PATH_MAX];
07954    struct ast_config *msg_cfg = NULL;
07955    const char *origtime, *context;
07956    char *cid, *name, *num;
07957    int retries = 0;
07958 
07959    vms->starting = 0; 
07960 #ifdef IMAP_STORAGE
07961    /* START HERE */
07962    /* get the message info!! */
07963    if (option_debug > 2)
07964       ast_log (LOG_DEBUG,"Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n",vms->curmsg, vms->msgArray[vms->curmsg]);
07965    if (vms->msgArray[vms->curmsg] == 0) {
07966       ast_log (LOG_WARNING,"Trying to access unknown message\n");
07967       return -1;
07968    }
07969 
07970    /* This will only work for new messages... */
07971    header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
07972    /* empty string means no valid header */
07973    if (ast_strlen_zero(header_content)) {
07974       ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
07975       return -1;
07976    }
07977 
07978    /* Get info from headers!! */
07979    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Caller-ID-Num:");
07980    
07981    if (temp)
07982       ast_copy_string(cidS,temp, sizeof(cidS));
07983    else
07984       cidS[0] = '\0';
07985    
07986    cid = &cidS[0];
07987    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Context:");
07988    
07989    if (temp)
07990       ast_copy_string(contextS,temp, sizeof(contextS));
07991    else
07992       contextS[0] = '\0';
07993    
07994    context = &contextS[0];
07995    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Orig-time:");
07996    
07997    if (temp)
07998       ast_copy_string(origtimeS,temp, sizeof(origtimeS));
07999    else
08000       origtimeS[0] = '\0';
08001    
08002    origtime = &origtimeS[0];
08003    
08004    ast_copy_string(filename, "IMAP_STORAGE", sizeof(filename));
08005 #else
08006    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08007 
08008    /* Retrieve info from VM attribute file */
08009 
08010    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
08011    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
08012    RETRIEVE(vms->curdir, vms->curmsg);
08013    msg_cfg = ast_config_load(filename);
08014    DISPOSE(vms->curdir, vms->curmsg);
08015    if (!msg_cfg) {
08016       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
08017       return 0;
08018    }
08019 
08020    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
08021       ast_config_destroy(msg_cfg);
08022       return 0;
08023    }
08024 
08025    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
08026 
08027    context = ast_variable_retrieve(msg_cfg, "message", "context");
08028    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
08029       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
08030 #endif
08031    switch (option) {
08032    case 3:
08033       if (!res)
08034          res = play_message_datetime(chan, vmu, origtime, filename);
08035       if (!res)
08036          res = play_message_callerid(chan, vms, cid, context, 0);
08037 
08038       res = 't';
08039       break;
08040 
08041    case 2:  /* Call back */
08042 
08043       if (ast_strlen_zero(cid))
08044          break;
08045 
08046       ast_callerid_parse(cid, &name, &num);
08047       while ((res > -1) && (res != 't')) {
08048          switch (res) {
08049          case '1':
08050             if (num) {
08051                /* Dial the CID number */
08052                res = dialout(chan, vmu, num, vmu->callback);
08053                if (res) {
08054                   ast_config_destroy(msg_cfg);
08055                   return 9;
08056                }
08057             } else {
08058                res = '2';
08059             }
08060             break;
08061 
08062          case '2':
08063             /* Want to enter a different number, can only do this if there's a dialout context for this user */
08064             if (!ast_strlen_zero(vmu->dialout)) {
08065                res = dialout(chan, vmu, NULL, vmu->dialout);
08066                if (res) {
08067                   ast_config_destroy(msg_cfg);
08068                   return 9;
08069                }
08070             } else {
08071                if (option_verbose > 2)
08072                   ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
08073                res = ast_play_and_wait(chan, "vm-sorry");
08074             }
08075             ast_config_destroy(msg_cfg);
08076             return res;
08077          case '*':
08078             res = 't';
08079             break;
08080          case '3':
08081          case '4':
08082          case '5':
08083          case '6':
08084          case '7':
08085          case '8':
08086          case '9':
08087          case '0':
08088 
08089             res = ast_play_and_wait(chan, "vm-sorry");
08090             retries++;
08091             break;
08092          default:
08093             if (num) {
08094                if (option_verbose > 2)
08095                   ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
08096                res = ast_play_and_wait(chan, "vm-num-i-have");
08097                if (!res)
08098                   res = play_message_callerid(chan, vms, num, vmu->context, 1);
08099                if (!res)
08100                   res = ast_play_and_wait(chan, "vm-tocallnum");
08101                /* Only prompt for a caller-specified number if there is a dialout context specified */
08102                if (!ast_strlen_zero(vmu->dialout)) {
08103                   if (!res)
08104                      res = ast_play_and_wait(chan, "vm-calldiffnum");
08105                }
08106             } else {
08107                res = ast_play_and_wait(chan, "vm-nonumber");
08108                if (!ast_strlen_zero(vmu->dialout)) {
08109                   if (!res)
08110                      res = ast_play_and_wait(chan, "vm-toenternumber");
08111                }
08112             }
08113             if (!res)
08114                res = ast_play_and_wait(chan, "vm-star-cancel");
08115             if (!res)
08116                res = ast_waitfordigit(chan, 6000);
08117             if (!res) {
08118                retries++;
08119                if (retries > 3)
08120                   res = 't';
08121             }
08122             break; 
08123             
08124          }
08125          if (res == 't')
08126             res = 0;
08127          else if (res == '*')
08128             res = -1;
08129       }
08130       break;
08131       
08132    case 1:  /* Reply */
08133       /* Send reply directly to sender */
08134       if (ast_strlen_zero(cid))
08135          break;
08136 
08137       ast_callerid_parse(cid, &name, &num);
08138       if (!num) {
08139          if (option_verbose > 2)
08140             ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
08141          if (!res)
08142             res = ast_play_and_wait(chan, "vm-nonumber");
08143          ast_config_destroy(msg_cfg);
08144          return res;
08145       } else {
08146          struct ast_vm_user vmu2;
08147          if (find_user(&vmu2, vmu->context, num)) {
08148             struct leave_vm_options leave_options;
08149             char mailbox[AST_MAX_EXTENSION * 2 + 2];
08150             snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
08151 
08152             if (option_verbose > 2)
08153                ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
08154             
08155             memset(&leave_options, 0, sizeof(leave_options));
08156             leave_options.record_gain = record_gain;
08157             res = leave_voicemail(chan, mailbox, &leave_options);
08158             if (!res)
08159                res = 't';
08160             ast_config_destroy(msg_cfg);
08161             return res;
08162          } else {
08163             /* Sender has no mailbox, can't reply */
08164             if (option_verbose > 2)
08165                ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
08166             ast_play_and_wait(chan, "vm-nobox");
08167             res = 't';
08168             ast_config_destroy(msg_cfg);
08169             return res;
08170          }
08171       } 
08172       res = 0;
08173 
08174       break;
08175    }
08176 
08177 #ifndef IMAP_STORAGE
08178    ast_config_destroy(msg_cfg);
08179 
08180    if (!res) {
08181       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08182       vms->heard[msg] = 1;
08183       res = wait_file(chan, vms, vms->fn);
08184    }
08185 #endif
08186    return res;
08187 }

static int append_mailbox ( char *  context,
char *  mbox,
char *  data 
) [static]

Definition at line 7058 of file app_voicemail.c.

References apply_options(), ast_strdupa, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, ast_vm_user::pager, ast_vm_user::password, populate_defaults(), s, and strsep().

Referenced by load_config().

07059 {
07060    /* Assumes lock is already held */
07061    char *tmp;
07062    char *stringp;
07063    char *s;
07064    struct ast_vm_user *vmu;
07065 
07066    tmp = ast_strdupa(data);
07067 
07068    if ((vmu = find_or_create(context, mbox))) {
07069       populate_defaults(vmu);
07070 
07071       stringp = tmp;
07072       if ((s = strsep(&stringp, ","))) 
07073          ast_copy_string(vmu->password, s, sizeof(vmu->password));
07074       if (stringp && (s = strsep(&stringp, ","))) 
07075          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
07076       if (stringp && (s = strsep(&stringp, ","))) 
07077          ast_copy_string(vmu->email, s, sizeof(vmu->email));
07078       if (stringp && (s = strsep(&stringp, ","))) 
07079          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
07080       if (stringp && (s = strsep(&stringp, ","))) 
07081          apply_options(vmu, s);
07082    }
07083    return 0;
07084 }

static void apply_option ( struct ast_vm_user vmu,
const char *  var,
const char *  value 
) [static]

Definition at line 575 of file app_voicemail.c.

References apply_options(), ast_log(), ast_set2_flag, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::exit, ast_vm_user::language, LOG_WARNING, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::saydurationm, ast_vm_user::serveremail, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.

Referenced by apply_options(), and apply_options_full().

00576 {
00577    int x;
00578    if (!strcasecmp(var, "attach")) {
00579       ast_set2_flag(vmu, ast_true(value), VM_ATTACH);
00580    } else if (!strcasecmp(var, "attachfmt")) {
00581       ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt));
00582    } else if (!strcasecmp(var, "serveremail")) {
00583       ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail));
00584    } else if (!strcasecmp(var, "language")) {
00585       ast_copy_string(vmu->language, value, sizeof(vmu->language));
00586    } else if (!strcasecmp(var, "tz")) {
00587       ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
00588 #ifdef IMAP_STORAGE
00589    } else if (!strcasecmp(var, "imapuser")) {
00590       ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser));
00591    } else if (!strcasecmp(var, "imappassword")) {
00592       ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword));
00593 #endif
00594    } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
00595       ast_set2_flag(vmu, ast_true(value), VM_DELETE); 
00596    } else if (!strcasecmp(var, "saycid")){
00597       ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 
00598    } else if (!strcasecmp(var,"sendvoicemail")){
00599       ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 
00600    } else if (!strcasecmp(var, "review")){
00601       ast_set2_flag(vmu, ast_true(value), VM_REVIEW);
00602    } else if (!strcasecmp(var, "tempgreetwarn")){
00603       ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN);   
00604    } else if (!strcasecmp(var, "operator")){
00605       ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);  
00606    } else if (!strcasecmp(var, "envelope")){
00607       ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE);  
00608    } else if (!strcasecmp(var, "sayduration")){
00609       ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION);  
00610    } else if (!strcasecmp(var, "saydurationm")){
00611       if (sscanf(value, "%d", &x) == 1) {
00612          vmu->saydurationm = x;
00613       } else {
00614          ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
00615       }
00616    } else if (!strcasecmp(var, "forcename")){
00617       ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 
00618    } else if (!strcasecmp(var, "forcegreetings")){
00619       ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET);   
00620    } else if (!strcasecmp(var, "callback")) {
00621       ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
00622    } else if (!strcasecmp(var, "dialout")) {
00623       ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout));
00624    } else if (!strcasecmp(var, "exitcontext")) {
00625       ast_copy_string(vmu->exit, value, sizeof(vmu->exit));
00626    } else if (!strcasecmp(var, "maxmsg")) {
00627       vmu->maxmsg = atoi(value);
00628       if (vmu->maxmsg <= 0) {
00629          ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %i\n", value, MAXMSG);
00630          vmu->maxmsg = MAXMSG;
00631       } else if (vmu->maxmsg > MAXMSGLIMIT) {
00632          ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value);
00633          vmu->maxmsg = MAXMSGLIMIT;
00634       }
00635    } else if (!strcasecmp(var, "volgain")) {
00636       sscanf(value, "%lf", &vmu->volgain);
00637    } else if (!strcasecmp(var, "options")) {
00638       apply_options(vmu, value);
00639    }
00640 }

static void apply_options ( struct ast_vm_user vmu,
const char *  options 
) [static]

Definition at line 658 of file app_voicemail.c.

References apply_option(), ast_strdupa, s, strsep(), and var.

Referenced by append_mailbox(), and apply_option().

00659 {  /* Destructively Parse options and apply */
00660    char *stringp;
00661    char *s;
00662    char *var, *value;
00663    stringp = ast_strdupa(options);
00664    while ((s = strsep(&stringp, "|"))) {
00665       value = s;
00666       if ((var = strsep(&value, "=")) && value) {
00667          apply_option(vmu, var, value);
00668       }
00669    }  
00670 }

static void apply_options_full ( struct ast_vm_user retval,
struct ast_variable var 
) [static]

Definition at line 672 of file app_voicemail.c.

References apply_option(), ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, ast_vm_user::fullname, ast_variable::name, ast_variable::next, ast_vm_user::pager, ast_vm_user::password, ast_vm_user::uniqueid, and ast_variable::value.

Referenced by find_user_realtime(), and load_config().

00673 {
00674    struct ast_variable *tmp;
00675    tmp = var;
00676    while (tmp) {
00677       if (!strcasecmp(tmp->name, "vmsecret")) {
00678          ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00679       } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
00680          if (ast_strlen_zero(retval->password))
00681             ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00682       } else if (!strcasecmp(tmp->name, "uniqueid")) {
00683          ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00684       } else if (!strcasecmp(tmp->name, "pager")) {
00685          ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00686       } else if (!strcasecmp(tmp->name, "email")) {
00687          ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00688       } else if (!strcasecmp(tmp->name, "fullname")) {
00689          ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00690       } else if (!strcasecmp(tmp->name, "context")) {
00691          ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00692 #ifdef IMAP_STORAGE
00693       } else if (!strcasecmp(tmp->name, "imapuser")) {
00694          ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
00695       } else if (!strcasecmp(tmp->name, "imappassword")) {
00696          ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
00697 #endif
00698       } else
00699          apply_option(retval, tmp->name, tmp->value);
00700       tmp = tmp->next;
00701    } 
00702 }

AST_APP_OPTIONS ( vm_app_options   ) 

static AST_LIST_HEAD_STATIC ( zones  ,
vm_zone   
) [static]

static AST_LIST_HEAD_STATIC ( users  ,
ast_vm_user   
) [static]

AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_DEFAULT  ,
tdesc  ,
load = load_module,
unload = unload_module,
reload = reload 
)

static int base_encode ( char *  filename,
FILE *  so 
) [static]

Definition at line 1626 of file app_voicemail.c.

References ast_log(), BASEMAXINLINE, eol, errno, inchar(), baseio::iocp, LOG_WARNING, and ochar().

Referenced by make_email_file().

01627 {
01628    unsigned char dtable[BASEMAXINLINE];
01629    int i,hiteof= 0;
01630    FILE *fi;
01631    struct baseio bio;
01632 
01633    memset(&bio, 0, sizeof(bio));
01634    bio.iocp = BASEMAXINLINE;
01635 
01636    if (!(fi = fopen(filename, "rb"))) {
01637       ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
01638       return -1;
01639    }
01640 
01641    for (i= 0;i<9;i++) {
01642       dtable[i]= 'A'+i;
01643       dtable[i+9]= 'J'+i;
01644       dtable[26+i]= 'a'+i;
01645       dtable[26+i+9]= 'j'+i;
01646    }
01647    for (i= 0;i<8;i++) {
01648       dtable[i+18]= 'S'+i;
01649       dtable[26+i+18]= 's'+i;
01650    }
01651    for (i= 0;i<10;i++) {
01652       dtable[52+i]= '0'+i;
01653    }
01654    dtable[62]= '+';
01655    dtable[63]= '/';
01656 
01657    while (!hiteof){
01658       unsigned char igroup[3],ogroup[4];
01659       int c,n;
01660 
01661       igroup[0]= igroup[1]= igroup[2]= 0;
01662 
01663       for (n= 0;n<3;n++) {
01664          if ((c = inchar(&bio, fi)) == EOF) {
01665             hiteof= 1;
01666             break;
01667          }
01668 
01669          igroup[n]= (unsigned char)c;
01670       }
01671 
01672       if (n> 0) {
01673          ogroup[0]= dtable[igroup[0]>>2];
01674          ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)];
01675          ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)];
01676          ogroup[3]= dtable[igroup[2]&0x3F];
01677 
01678          if (n<3) {
01679             ogroup[3]= '=';
01680 
01681             if (n<2)
01682                ogroup[2]= '=';
01683          }
01684 
01685          for (i= 0;i<4;i++)
01686             ochar(&bio, ogroup[i], so);
01687       }
01688    }
01689 
01690    fclose(fi);
01691    
01692    if (fputs(eol,so)==EOF)
01693       return 0;
01694 
01695    return 1;
01696 }

static int change_password_realtime ( struct ast_vm_user vmu,
const char *  password 
) [static]

Definition at line 642 of file app_voicemail.c.

References ast_strlen_zero(), ast_update_realtime(), ast_vm_user::password, and ast_vm_user::uniqueid.

Referenced by vm_change_password().

00643 {
00644    int res;
00645    if (!ast_strlen_zero(vmu->uniqueid)) {
00646       res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL);
00647       if (res > 0) {
00648          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00649          res = 0;
00650       } else if (!res) {
00651          res = -1;
00652       }
00653       return res;
00654    }
00655    return -1;
00656 }

static int close_mailbox ( struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 4838 of file app_voicemail.c.

References ast_log(), ast_unlock_path(), ast_vm_user::context, vm_state::curbox, vm_state::curdir, vm_state::curmsg, DELETE, vm_state::deleted, ERROR_LOCK_PATH, EXISTS, vm_state::fn, vm_state::fn2, vm_state::heard, vm_state::lastmsg, LOG_DEBUG, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, option_debug, RENAME, save_to_folder(), and vm_lock_path().

Referenced by vm_execmain().

04839 {
04840    int x = 0;
04841 #ifndef IMAP_STORAGE
04842    int res = 0, nummsg;
04843 #endif
04844 
04845    if (vms->lastmsg <= -1)
04846       goto done;
04847 
04848    vms->curmsg = -1; 
04849 #ifndef IMAP_STORAGE
04850    /* Get the deleted messages fixed */ 
04851    if (vm_lock_path(vms->curdir))
04852       return ERROR_LOCK_PATH;
04853     
04854    for (x = 0; x < vmu->maxmsg; x++) { 
04855       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
04856          /* Save this message.  It's not in INBOX or hasn't been heard */ 
04857          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
04858          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
04859             break;
04860          vms->curmsg++; 
04861          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
04862          if (strcmp(vms->fn, vms->fn2)) { 
04863             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
04864          } 
04865       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
04866          /* Move to old folder before deleting */ 
04867          res = save_to_folder(vmu, vms, x, 1);
04868          if (res == ERROR_LOCK_PATH) {
04869             /* If save failed do not delete the message */
04870             vms->deleted[x] = 0;
04871             vms->heard[x] = 0;
04872             --x;
04873          } 
04874       } 
04875    } 
04876 
04877    /* Delete ALL remaining messages */
04878    nummsg = x - 1;
04879    for (x = vms->curmsg + 1; x <= nummsg; x++) {
04880       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
04881       if (EXISTS(vms->curdir, x, vms->fn, NULL))
04882          DELETE(vms->curdir, x, vms->fn);
04883    }
04884    ast_unlock_path(vms->curdir);
04885 #else
04886    if (vms->deleted) {
04887       for (x=0;x < vmu->maxmsg;x++) { 
04888          if (vms->deleted[x]) { 
04889             if (option_debug > 2)
04890                ast_log(LOG_DEBUG,"IMAP delete of %d\n",x);
04891             IMAP_DELETE(vms->curdir, x, vms->fn, vms);
04892          }
04893       }
04894    }
04895 #endif
04896 
04897 done:
04898    if (vms->deleted)
04899       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
04900    if (vms->heard)
04901       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
04902 
04903    return 0;
04904 }

static char* complete_voicemail_show_users ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 7247 of file app_voicemail.c.

References AST_LIST_TRAVERSE, ast_strdup, ast_vm_user::context, and users.

07248 {
07249    int which = 0;
07250    int wordlen;
07251    struct ast_vm_user *vmu;
07252    const char *context = "";
07253 
07254    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
07255    if (pos > 4)
07256       return NULL;
07257    if (pos == 3)
07258       return (state == 0) ? ast_strdup("for") : NULL;
07259    wordlen = strlen(word);
07260    AST_LIST_TRAVERSE(&users, vmu, list) {
07261       if (!strncasecmp(word, vmu->context, wordlen)) {
07262          if (context && strcmp(context, vmu->context) && ++which > state)
07263             return ast_strdup(vmu->context);
07264          /* ignore repeated contexts ? */
07265          context = vmu->context;
07266       }
07267    }
07268    return NULL;
07269 }

static int copy ( char *  infile,
char *  outfile 
) [static]

Definition at line 1478 of file app_voicemail.c.

References ast_log(), errno, LOG_WARNING, and VOICEMAIL_FILE_MODE.

01479 {
01480    int ifd;
01481    int ofd;
01482    int res;
01483    int len;
01484    char buf[4096];
01485 
01486 #ifdef HARDLINK_WHEN_POSSIBLE
01487    /* Hard link if possible; saves disk space & is faster */
01488    if (link(infile, outfile)) {
01489 #endif
01490       if ((ifd = open(infile, O_RDONLY)) < 0) {
01491          ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
01492          return -1;
01493       }
01494       if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
01495          ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
01496          close(ifd);
01497          return -1;
01498       }
01499       do {
01500          len = read(ifd, buf, sizeof(buf));
01501          if (len < 0) {
01502             ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
01503             close(ifd);
01504             close(ofd);
01505             unlink(outfile);
01506          }
01507          if (len) {
01508             res = write(ofd, buf, len);
01509             if (errno == ENOMEM || errno == ENOSPC || res != len) {
01510                ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
01511                close(ifd);
01512                close(ofd);
01513                unlink(outfile);
01514             }
01515          }
01516       } while (len);
01517       close(ifd);
01518       close(ofd);
01519       return 0;
01520 #ifdef HARDLINK_WHEN_POSSIBLE
01521    } else {
01522       /* Hard link succeeded */
01523       return 0;
01524    }
01525 #endif
01526 }

static void copy_file ( char *  frompath,
char *  topath 
) [static]

Definition at line 1528 of file app_voicemail.c.

References ast_filecopy(), and copy().

01529 {
01530    char frompath2[PATH_MAX], topath2[PATH_MAX];
01531    ast_filecopy(frompath, topath, NULL);
01532    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
01533    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
01534    copy(frompath2, topath2);
01535 }

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 
) [static]

Definition at line 2590 of file app_voicemail.c.

References ast_log(), ast_unlock_path(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, COPY, create_dirpath(), ERROR_LOCK_PATH, EXISTS, LOG_ERROR, LOG_NOTICE, ast_vm_user::mailbox, make_dir(), make_file(), ast_vm_user::maxmsg, mbox(), notify_new_message(), S_OR, and vm_lock_path().

Referenced by forward_message(), and leave_voicemail().

02591 {
02592    char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
02593    const char *frombox = mbox(imbox);
02594    int recipmsgnum;
02595 
02596    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
02597 
02598    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
02599    
02600    if (!dir)
02601       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
02602    else
02603       ast_copy_string(fromdir, dir, sizeof(fromdir));
02604 
02605    make_file(frompath, sizeof(frompath), fromdir, msgnum);
02606 
02607    if (vm_lock_path(todir))
02608       return ERROR_LOCK_PATH;
02609 
02610    recipmsgnum = 0;
02611    do {
02612       make_file(topath, sizeof(topath), todir, recipmsgnum);
02613       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
02614          break;
02615       recipmsgnum++;
02616    } while (recipmsgnum < recip->maxmsg);
02617    if (recipmsgnum < recip->maxmsg) {
02618       COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
02619    } else {
02620       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
02621    }
02622    ast_unlock_path(todir);
02623    notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
02624    
02625    return 0;
02626 }

static int count_messages ( struct ast_vm_user vmu,
char *  dir 
) [static]

Definition at line 1445 of file app_voicemail.c.

References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().

Referenced by leave_voicemail(), and open_mailbox().

01446 {
01447    /* Find all .txt files - even if they are not in sequence from 0000 */
01448 
01449    int vmcount = 0;
01450    DIR *vmdir = NULL;
01451    struct dirent *vment = NULL;
01452 
01453    if (vm_lock_path(dir))
01454       return ERROR_LOCK_PATH;
01455 
01456    if ((vmdir = opendir(dir))) {
01457       while ((vment = readdir(vmdir))) {
01458          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
01459             vmcount++;
01460       }
01461       closedir(vmdir);
01462    }
01463    ast_unlock_path(dir);
01464    
01465    return vmcount;
01466 }

static int create_dirpath ( char *  dest,
int  len,
const char *  context,
const char *  ext,
const char *  folder 
) [static]

basically mkdir -p $dest/$context/$ext/$folder

Parameters:
dest String. base directory.
len Length of dest.
context String. Ignored if is null or empty string.
ext String. Ignored if is null or empty string.
folder String. Ignored if is null or empty string.
Returns:
-1 on failure, 0 on success.

Definition at line 912 of file app_voicemail.c.

References ast_log(), ast_strlen_zero(), errno, LOG_WARNING, make_dir(), and VOICEMAIL_DIR_MODE.

Referenced by copy_message(), invent_message(), leave_voicemail(), make_email_file(), open_mailbox(), save_to_folder(), vm_execmain(), and vm_tempgreeting().

00913 {
00914    mode_t   mode = VOICEMAIL_DIR_MODE;
00915 
00916    if (!ast_strlen_zero(context)) {
00917       make_dir(dest, len, context, "", "");
00918       if (mkdir(dest, mode) && errno != EEXIST) {
00919          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00920          return -1;
00921       }
00922    }
00923    if (!ast_strlen_zero(ext)) {
00924       make_dir(dest, len, context, ext, "");
00925       if (mkdir(dest, mode) && errno != EEXIST) {
00926          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00927          return -1;
00928       }
00929    }
00930    if (!ast_strlen_zero(folder)) {
00931       make_dir(dest, len, context, ext, folder);
00932       if (mkdir(dest, mode) && errno != EEXIST) {
00933          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00934          return -1;
00935       }
00936    }
00937    return 0;
00938 }

static int dialout ( struct ast_channel chan,
struct ast_vm_user vmu,
char *  num,
char *  outgoing_context 
) [static]

Definition at line 7885 of file app_voicemail.c.

References ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_verbose(), ast_waitfordigit(), ast_channel::context, ast_channel::exten, option_verbose, ast_channel::priority, and VERBOSE_PREFIX_3.

07886 {
07887    int cmd = 0;
07888    char destination[80] = "";
07889    int retries = 0;
07890 
07891    if (!num) {
07892       if (option_verbose > 2)
07893          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
07894       while (retries < 3 && cmd != 't') {
07895          destination[1] = '\0';
07896          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
07897          if (!cmd)
07898             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
07899          if (!cmd)
07900             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
07901          if (!cmd) {
07902             cmd = ast_waitfordigit(chan, 6000);
07903             if (cmd)
07904                destination[0] = cmd;
07905          }
07906          if (!cmd) {
07907             retries++;
07908          } else {
07909 
07910             if (cmd < 0)
07911                return 0;
07912             if (cmd == '*') {
07913                if (option_verbose > 2)
07914                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
07915                return 0;
07916             }
07917             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
07918                retries++;
07919             else
07920                cmd = 't';
07921          }
07922       }
07923       if (retries >= 3) {
07924          return 0;
07925       }
07926       
07927    } else {
07928       if (option_verbose > 2)
07929          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
07930       ast_copy_string(destination, num, sizeof(destination));
07931    }
07932 
07933    if (!ast_strlen_zero(destination)) {
07934       if (destination[strlen(destination) -1 ] == '*')
07935          return 0; 
07936       if (option_verbose > 2)
07937          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
07938       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
07939       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
07940       chan->priority = 0;
07941       return 9;
07942    }
07943    return 0;
07944 }

static struct ast_vm_user* find_or_create ( char *  context,
char *  mbox 
) [static, read]

Definition at line 7038 of file app_voicemail.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_test_flag, ast_vm_user::context, globalflags, ast_vm_user::mailbox, users, and VM_SEARCH.

Referenced by append_mailbox(), and load_config().

07039 {
07040    struct ast_vm_user *vmu;
07041    AST_LIST_TRAVERSE(&users, vmu, list) {
07042       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox))
07043          break;
07044       if (context && (!strcasecmp(context, vmu->context)) && (!strcasecmp(mbox, vmu->mailbox)))
07045          break;
07046    }
07047    
07048    if (!vmu) {
07049       if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
07050          ast_copy_string(vmu->context, context, sizeof(vmu->context));
07051          ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
07052          AST_LIST_INSERT_TAIL(&users, vmu, list);
07053       }
07054    }
07055    return vmu;
07056 }

static struct ast_vm_user* find_user ( struct ast_vm_user ivm,
const char *  context,
const char *  mailbox 
) [static, read]

Definition at line 733 of file app_voicemail.c.

References AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_malloc, ast_set2_flag, ast_test_flag, find_user_realtime(), globalflags, users, VM_ALLOCED, and VM_SEARCH.

00734 {
00735    /* This function could be made to generate one from a database, too */
00736    struct ast_vm_user *vmu=NULL, *cur;
00737    AST_LIST_LOCK(&users);
00738 
00739    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00740       context = "default";
00741 
00742    AST_LIST_TRAVERSE(&users, cur, list) {
00743       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00744          break;
00745       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00746          break;
00747    }
00748    if (cur) {
00749       /* Make a copy, so that on a reload, we have no race */
00750       if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
00751          memcpy(vmu, cur, sizeof(*vmu));
00752          ast_set2_flag(vmu, !ivm, VM_ALLOCED);
00753          AST_LIST_NEXT(vmu, list) = NULL;
00754       }
00755    } else
00756       vmu = find_user_realtime(ivm, context, mailbox);
00757    AST_LIST_UNLOCK(&users);
00758    return vmu;
00759 }

static struct ast_vm_user* find_user_realtime ( struct ast_vm_user ivm,
const char *  context,
const char *  mailbox 
) [static, read]

Definition at line 704 of file app_voicemail.c.

References apply_options_full(), ast_calloc, ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), free, globalflags, ast_vm_user::mailbox, populate_defaults(), var, VM_ALLOCED, and VM_SEARCH.

Referenced by find_user().

00705 {
00706    struct ast_variable *var;
00707    struct ast_vm_user *retval;
00708 
00709    if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
00710       if (!ivm)
00711          ast_set_flag(retval, VM_ALLOCED);   
00712       else
00713          memset(retval, 0, sizeof(*retval));
00714       if (mailbox) 
00715          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00716       populate_defaults(retval);
00717       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00718          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00719       else
00720          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00721       if (var) {
00722          apply_options_full(retval, var);
00723          ast_variables_destroy(var);
00724       } else { 
00725          if (!ivm) 
00726             free(retval);
00727          retval = NULL;
00728       }  
00729    } 
00730    return retval;
00731 }

static int forward_message ( struct ast_channel chan,
char *  context,
struct vm_state vms,
struct ast_vm_user sender,
char *  fmt,
int  flag,
signed char  record_gain 
) [static]

Definition at line 3958 of file app_voicemail.c.

References app, ast_clear_flag, AST_LIST_EMPTY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, copy_message(), vm_state::curdir, vm_state::curmsg, ast_channel::exten, find_user(), vm_state::fn, free_user(), globalflags, leave_voicemail(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_vm_user::mailbox, option_debug, pbx_exec(), pbx_findapp(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, run_externnotify(), s, S_OR, sendmail(), ast_vm_user::serveremail, STORE, strsep(), username, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), VM_SPOOL_DIR, and vmfmts.

Referenced by vm_execmain().

03959 {
03960 #ifdef IMAP_STORAGE
03961    BODY *body;
03962    char *header_content;
03963    char *temp;
03964    char todir[256];
03965    int todircount=0;
03966    struct vm_state *dstvms;
03967 #endif
03968    char username[70]="";
03969    int res = 0, cmd = 0;
03970    struct ast_vm_user *receiver = NULL, *vmtmp;
03971    AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
03972    char *stringp;
03973    const char *s;
03974    int saved_messages = 0, found = 0;
03975    int valid_extensions = 0;
03976    char *dir;
03977    int curmsg;
03978 
03979    if (vms == NULL) return -1;
03980    dir = vms->curdir;
03981    curmsg = vms->curmsg;
03982    
03983    while (!res && !valid_extensions) {
03984       int use_directory = 0;
03985       if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
03986          int done = 0;
03987          int retries = 0;
03988          cmd=0;
03989          while ((cmd >= 0) && !done ){
03990             if (cmd)
03991                retries = 0;
03992             switch (cmd) {
03993             case '1': 
03994                use_directory = 0;
03995                done = 1;
03996                break;
03997             case '2': 
03998                use_directory = 1;
03999                done=1;
04000                break;
04001             case '*': 
04002                cmd = 't';
04003                done = 1;
04004                break;
04005             default: 
04006                /* Press 1 to enter an extension press 2 to use the directory */
04007                cmd = ast_play_and_wait(chan,"vm-forward");
04008                if (!cmd)
04009                   cmd = ast_waitfordigit(chan,3000);
04010                if (!cmd)
04011                   retries++;
04012                if (retries > 3)
04013                {
04014                   cmd = 't';
04015                   done = 1;
04016                }
04017                
04018             }
04019          }
04020          if (cmd < 0 || cmd == 't')
04021             break;
04022       }
04023       
04024       if (use_directory) {
04025          /* use app_directory */
04026          
04027          char old_context[sizeof(chan->context)];
04028          char old_exten[sizeof(chan->exten)];
04029          int old_priority;
04030          struct ast_app* app;
04031 
04032          
04033          app = pbx_findapp("Directory");
04034          if (app) {
04035             char vmcontext[256];
04036             /* make backup copies */
04037             memcpy(old_context, chan->context, sizeof(chan->context));
04038             memcpy(old_exten, chan->exten, sizeof(chan->exten));
04039             old_priority = chan->priority;
04040             
04041             /* call the the Directory, changes the channel */
04042             snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default");
04043             res = pbx_exec(chan, app, vmcontext);
04044             
04045             ast_copy_string(username, chan->exten, sizeof(username));
04046             
04047             /* restore the old context, exten, and priority */
04048             memcpy(chan->context, old_context, sizeof(chan->context));
04049             memcpy(chan->exten, old_exten, sizeof(chan->exten));
04050             chan->priority = old_priority;
04051             
04052          } else {
04053             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
04054             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
04055          }
04056       } else {
04057          /* Ask for an extension */
04058          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
04059          if (res)
04060             break;
04061          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
04062             break;
04063       }
04064       
04065       /* start all over if no username */
04066       if (ast_strlen_zero(username))
04067          continue;
04068       stringp = username;
04069       s = strsep(&stringp, "*");
04070       /* start optimistic */
04071       valid_extensions = 1;
04072       while (s) {
04073          /* Don't forward to ourselves.  find_user is going to malloc since we have a NULL as first argument */
04074          if (strcmp(s,sender->mailbox) && (receiver = find_user(NULL, context, s))) {
04075             AST_LIST_INSERT_HEAD(&extensions, receiver, list);
04076             found++;
04077          } else {
04078             valid_extensions = 0;
04079             break;
04080          }
04081          s = strsep(&stringp, "*");
04082       }
04083       /* break from the loop of reading the extensions */
04084       if (valid_extensions)
04085          break;
04086       /* "I am sorry, that's not a valid extension.  Please try again." */
04087       res = ast_play_and_wait(chan, "pbx-invalid");
04088    }
04089    /* check if we're clear to proceed */
04090    if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
04091       return res;
04092    if (flag==1) {
04093       struct leave_vm_options leave_options;
04094       char mailbox[AST_MAX_EXTENSION * 2 + 2];
04095       snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
04096 
04097       /* Send VoiceMail */
04098       memset(&leave_options, 0, sizeof(leave_options));
04099       leave_options.record_gain = record_gain;
04100       cmd = leave_voicemail(chan, mailbox, &leave_options);
04101    } else {
04102 
04103       /* Forward VoiceMail */
04104       long duration = 0;
04105       RETRIEVE(dir, curmsg);
04106       cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, vms);
04107       if (!cmd) {
04108          AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
04109 #ifdef IMAP_STORAGE
04110             char *myserveremail;
04111             int attach_user_voicemail;
04112             /* Need to get message content */
04113             if (option_debug > 2)
04114                ast_log (LOG_DEBUG,"Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n",vms->curmsg, vms->msgArray[vms->curmsg]);
04115             if (vms->msgArray[vms->curmsg] == 0) {
04116                ast_log (LOG_WARNING,"Trying to access unknown message\n");
04117                return -1;
04118             }
04119 
04120             /* This will only work for new messages... */
04121             header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
04122             /* empty string means no valid header */
04123             if (ast_strlen_zero(header_content)) {
04124                ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
04125                return -1;
04126             }
04127             /* Get header info needed by sendmail */
04128             temp = get_header_by_tag(header_content, "X-Asterisk-VM-Duration:");
04129             if (temp)
04130                duration = atoi(temp);
04131             else
04132                duration = 0;
04133 
04134             /* Attach only the first format */
04135             fmt = ast_strdupa(fmt);
04136             if (fmt) {
04137                stringp = fmt;
04138                strsep(&stringp, "|");
04139             } else {
04140                ast_log (LOG_ERROR,"audio format not set. Default to WAV\n");
04141                fmt = "WAV";
04142             }
04143             if (!strcasecmp(fmt, "wav49"))
04144                fmt = "WAV";
04145             if (option_debug > 2)
04146                ast_log (LOG_DEBUG,"**** format set to %s, vmfmts set to %s\n",fmt,vmfmts);
04147             /* ast_copy_string(fmt, vmfmts, sizeof(fmt));*/
04148             /* if (!ast_strlen_zero(fmt)) { */
04149             snprintf(todir, sizeof(todir), "%s%s/%s/tmp", VM_SPOOL_DIR, vmtmp->context, vmtmp->mailbox);
04150             make_gsm_file(vms->fn, sizeof(vms->fn), vms->imapuser, todir, vms->curmsg);
04151             if (option_debug > 2)
04152                ast_log (LOG_DEBUG,"Before mail_fetchstructure, message number is %ld, filename is:%s\n",vms->msgArray[vms->curmsg], vms->fn);
04153             /*mail_fetchstructure (mailstream, vmArray[0], &body); */
04154             mail_fetchstructure (vms->mailstream, vms->msgArray[vms->curmsg], &body);
04155             save_body(body,vms,"3","gsm");
04156             /* should not assume "fmt" here! */
04157             save_body(body,vms,"2",fmt);
04158 
04159             /* get destination mailbox */
04160             dstvms = get_vm_state_by_mailbox(vmtmp->mailbox,0);
04161             if (dstvms) {
04162                init_mailstream(dstvms, 0);
04163                if (!dstvms->mailstream) {
04164                   ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
04165                } else {
04166                   STORE(todir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
04167                   run_externnotify(vmtmp->context, vmtmp->mailbox); 
04168                }
04169             } else {
04170                ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
04171             }
04172 
04173             myserveremail = serveremail;
04174             if (!ast_strlen_zero(vmtmp->serveremail))
04175                myserveremail = vmtmp->serveremail;
04176             attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
04177             attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
04178             /* NULL category for IMAP storage */
04179             sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vms->fn, fmt, duration, attach_user_voicemail, chan, NULL);
04180 #else
04181             copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir);
04182 #endif
04183             saved_messages++;
04184             AST_LIST_REMOVE_CURRENT(&extensions, list);
04185             free_user(vmtmp);
04186             if (res)
04187                break;
04188          }
04189          AST_LIST_TRAVERSE_SAFE_END;
04190          if (saved_messages > 0) {
04191             /* give confirmation that the message was saved */
04192             /* commented out since we can't forward batches yet
04193             if (saved_messages == 1)
04194                res = ast_play_and_wait(chan, "vm-message");
04195             else
04196                res = ast_play_and_wait(chan, "vm-messages");
04197             if (!res)
04198                res = ast_play_and_wait(chan, "vm-saved"); */
04199             res = ast_play_and_wait(chan, "vm-msgsaved");
04200          }  
04201       }
04202    }
04203 
04204    /* If anything failed above, we still have this list to free */
04205    while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list)))
04206       free_user(vmtmp);
04207    return res ? res : cmd;
04208 }

static void free_user ( struct ast_vm_user vmu  )  [static]

Definition at line 2096 of file app_voicemail.c.

References ast_test_flag, free, and VM_ALLOCED.

Referenced by forward_message(), leave_voicemail(), load_config(), and vm_execmain().

02097 {
02098    if (ast_test_flag(vmu, VM_ALLOCED))
02099       free(vmu);
02100 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 2102 of file app_voicemail.c.

References free.

02103 {
02104    free(z);
02105 }

static int get_date ( char *  s,
int  len 
) [static]

Definition at line 2050 of file app_voicemail.c.

References ast_localtime(), and t.

Referenced by leave_voicemail(), and tds_log().

02051 {
02052    struct tm tm;
02053    time_t t;
02054 
02055    time(&t);
02056 
02057    ast_localtime(&t, &tm, NULL);
02058 
02059    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
02060 }

static int get_folder ( struct ast_channel chan,
int  start 
) [static]

Definition at line 3770 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_waitfordigit(), mbox(), and vm_play_folder_name().

Referenced by get_folder2().

03771 {
03772    int x;
03773    int d;
03774    char fn[PATH_MAX];
03775    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
03776    if (d)
03777       return d;
03778    for (x = start; x< 5; x++) {  /* For all folders */
03779       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
03780          return d;
03781       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
03782       if (d)
03783          return d;
03784       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
03785       d = vm_play_folder_name(chan, fn);
03786       if (d)
03787          return d;
03788       d = ast_waitfordigit(chan, 500);
03789       if (d)
03790          return d;
03791    }
03792    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
03793    if (d)
03794       return d;
03795    d = ast_waitfordigit(chan, 4000);
03796    return d;
03797 }

static int get_folder2 ( struct ast_channel chan,
char *  fn,
int  start 
) [static]

Definition at line 3799 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

03800 {
03801    int res = 0;
03802    res = ast_play_and_wait(chan, fn);  /* Folder name */
03803    while (((res < '0') || (res > '9')) &&
03804          (res != '#') && (res >= 0)) {
03805       res = get_folder(chan, 0);
03806    }
03807    return res;
03808 }

static int get_lastdigits ( int  num  )  [static]

Definition at line 5633 of file app_voicemail.c.

Referenced by vm_intro_ru(), and vm_intro_ua().

05634 {
05635    num %= 100;
05636    return (num < 20) ? num : num % 10;
05637 }

static int handle_voicemail_show_users ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 7177 of file app_voicemail.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::fullname, inboxcount(), ast_vm_user::mailbox, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, users, and ast_vm_user::zonetag.

07178 {
07179    struct ast_vm_user *vmu;
07180    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
07181 
07182    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
07183    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
07184 
07185    AST_LIST_LOCK(&users);
07186    if (!AST_LIST_EMPTY(&users)) {
07187       if (argc == 3)
07188          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
07189       else {
07190          int count = 0;
07191          AST_LIST_TRAVERSE(&users, vmu, list) {
07192             if (!strcmp(argv[4],vmu->context))
07193                count++;
07194          }
07195          if (count) {
07196             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
07197          } else {
07198             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
07199             AST_LIST_UNLOCK(&users);
07200             return RESULT_FAILURE;
07201          }
07202       }
07203       AST_LIST_TRAVERSE(&users, vmu, list) {
07204          int newmsgs = 0, oldmsgs = 0;
07205          char count[12], tmp[256] = "";
07206 
07207          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
07208             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
07209             inboxcount(tmp, &newmsgs, &oldmsgs);
07210             snprintf(count,sizeof(count),"%d",newmsgs);
07211             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
07212          }
07213       }
07214    } else {
07215       ast_cli(fd, "There are no voicemail users currently defined\n");
07216       AST_LIST_UNLOCK(&users);
07217       return RESULT_FAILURE;
07218    }
07219    AST_LIST_UNLOCK(&users);
07220    return RESULT_SUCCESS;
07221 }

static int handle_voicemail_show_zones ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 7223 of file app_voicemail.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

07224 {
07225    struct vm_zone *zone;
07226    char *output_format = "%-15s %-20s %-45s\n";
07227    int res = RESULT_SUCCESS;
07228 
07229    if (argc != 3)
07230       return RESULT_SHOWUSAGE;
07231 
07232    AST_LIST_LOCK(&zones);
07233    if (!AST_LIST_EMPTY(&zones)) {
07234       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
07235       AST_LIST_TRAVERSE(&zones, zone, list) {
07236          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
07237       }
07238    } else {
07239       ast_cli(fd, "There are no voicemail zones currently defined\n");
07240       res = RESULT_FAILURE;
07241    }
07242    AST_LIST_UNLOCK(&zones);
07243 
07244    return res;
07245 }

static int has_voicemail ( const char *  mailbox,
const char *  folder 
) [static]

Definition at line 2666 of file app_voicemail.c.

References __has_voicemail(), and strsep().

02667 {
02668    char tmp[256], *tmp2 = tmp, *mbox, *context;
02669    ast_copy_string(tmp, mailbox, sizeof(tmp));
02670    while ((mbox = strsep(&tmp2, ","))) {
02671       if ((context = strchr(mbox, '@')))
02672          *context++ = '\0';
02673       else
02674          context = "default";
02675       if (__has_voicemail(context, mbox, folder, 1))
02676          return 1;
02677    }
02678    return 0;
02679 }

static int inboxcount ( const char *  mailbox,
int *  newmsgs,
int *  oldmsgs 
) [static]

Definition at line 2682 of file app_voicemail.c.

References __has_voicemail(), ast_strlen_zero(), and strsep().

Referenced by handle_voicemail_show_users(), leave_voicemail(), load_module(), and run_externnotify().

02683 {
02684    char tmp[256];
02685    char *context;
02686 
02687    if (newmsgs)
02688       *newmsgs = 0;
02689    if (oldmsgs)
02690       *oldmsgs = 0;
02691    /* If no mailbox, return immediately */
02692    if (ast_strlen_zero(mailbox))
02693       return 0;
02694    if (strchr(mailbox, ',')) {
02695       int tmpnew, tmpold;
02696       char *mb, *cur;
02697 
02698       ast_copy_string(tmp, mailbox, sizeof(tmp));
02699       mb = tmp;
02700       while ((cur = strsep(&mb, ", "))) {
02701          if (!ast_strlen_zero(cur)) {
02702             if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
02703                return -1;
02704             else {
02705                if (newmsgs)
02706                   *newmsgs += tmpnew; 
02707                if (oldmsgs)
02708                   *oldmsgs += tmpold;
02709             }
02710          }
02711       }
02712       return 0;
02713    }
02714    ast_copy_string(tmp, mailbox, sizeof(tmp));
02715    context = strchr(tmp, '@');
02716    if (context) {
02717       *context = '\0';
02718       context++;
02719    } else
02720       context = "default";
02721    if (newmsgs)
02722       *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
02723    if (oldmsgs)
02724       *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
02725    return 0;
02726 }

static int inbuf ( struct baseio bio,
FILE *  fi 
) [static]

Definition at line 1578 of file app_voicemail.c.

References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.

Referenced by inchar(), and sip_addheader().

01579 {
01580    int l;
01581 
01582    if (bio->ateof)
01583       return 0;
01584 
01585    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
01586       if (ferror(fi))
01587          return -1;
01588 
01589       bio->ateof = 1;
01590       return 0;
01591    }
01592 
01593    bio->iolen= l;
01594    bio->iocp= 0;
01595 
01596    return 1;
01597 }

static int inchar ( struct baseio bio,
FILE *  fi 
) [static]

Definition at line 1599 of file app_voicemail.c.

References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.

Referenced by base_encode().

01600 {
01601    if (bio->iocp>=bio->iolen) {
01602       if (!inbuf(bio, fi))
01603          return EOF;
01604    }
01605 
01606    return bio->iobuf[bio->iocp++];
01607 }

static int invent_message ( struct ast_channel chan,
char *  context,
char *  ext,
int  busy,
char *  ecodes 
) [static]

Definition at line 2062 of file app_voicemail.c.

References ast_fileexists(), ast_log(), ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, LOG_WARNING, RETRIEVE, and VM_SPOOL_DIR.

Referenced by leave_voicemail().

02063 {
02064    int res;
02065    char fn[PATH_MAX];
02066    char dest[PATH_MAX];
02067 
02068    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext);
02069 
02070    if ((res = create_dirpath(dest, sizeof(dest), context, ext, "greet"))) {
02071       ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
02072       return -1;
02073    }
02074 
02075    RETRIEVE(fn, -1);
02076    if (ast_fileexists(fn, NULL, NULL) > 0) {
02077       res = ast_stream_and_wait(chan, fn, chan->language, ecodes);
02078       if (res) {
02079          DISPOSE(fn, -1);
02080          return res;
02081       }
02082    } else {
02083       /* Dispose just in case */
02084       DISPOSE(fn, -1);
02085       res = ast_stream_and_wait(chan, "vm-theperson", chan->language, ecodes);
02086       if (res)
02087          return res;
02088       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
02089       if (res)
02090          return res;
02091    }
02092    res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language, ecodes);
02093    return res;
02094 }

static int last_message_index ( struct ast_vm_user vmu,
char *  dir 
) [static]

Definition at line 1541 of file app_voicemail.c.

References ast_fileexists(), ast_unlock_path(), ERROR_LOCK_PATH, make_file(), ast_vm_user::maxmsg, and vm_lock_path().

Referenced by open_mailbox().

01542 {
01543    int x;
01544    char fn[PATH_MAX];
01545 
01546    if (vm_lock_path(dir))
01547       return ERROR_LOCK_PATH;
01548 
01549    for (x = 0; x < vmu->maxmsg; x++) {
01550       make_file(fn, sizeof(fn), dir, x);
01551       if (ast_fileexists(fn, NULL, NULL) < 1)
01552          break;
01553    }
01554    ast_unlock_path(dir);
01555 
01556    return x - 1;
01557 }

static int leave_voicemail ( struct ast_channel chan,
char *  ext,
struct leave_vm_options options 
) [static]

Definition at line 2777 of file app_voicemail.c.

References ast_callerid_merge(), ast_calloc, ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_goto_if_exists(), ast_log(), ast_opt_priority_jumping, ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_verbose(), ast_waitstream(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, ast_channel::context, copy_message(), count_messages(), create_dirpath(), vm_state::curbox, DISPOSE, errno, EXISTS, ast_vm_user::exit, exten, ast_channel::exten, find_user(), free_user(), get_date(), inboxcount(), INTRO, invent_message(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, my_umask, vm_state::newmessages, notify_new_message(), OPT_BUSY_GREETING, OPT_PRIORITY_JUMP, OPT_SILENT, OPT_UNAVAIL_GREETING, option_debug, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, S_OR, STORE, strsep(), transfer, vm_state::username, VERBOSE_PREFIX_3, vm_lock_path(), VM_OPERATOR, VM_SPOOL_DIR, vmfmts, vmmaxmessage, vmminmessage, and VOICEMAIL_FILE_MODE.

Referenced by advanced_options(), forward_message(), and vm_exec().

02778 {
02779 #ifdef IMAP_STORAGE
02780    int newmsgs, oldmsgs;
02781    struct vm_state *vms = NULL;
02782 #endif
02783    char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
02784    char callerid[256];
02785    FILE *txt;
02786    char date[256];
02787    int txtdes;
02788    int res = 0;
02789    int msgnum;
02790    int duration = 0;
02791    int ausemacro = 0;
02792    int ousemacro = 0;
02793    int ouseexten = 0;
02794    char dir[PATH_MAX], tmpdir[PATH_MAX];
02795    char dest[PATH_MAX];
02796    char fn[PATH_MAX];
02797    char prefile[PATH_MAX] = "";
02798    char tempfile[PATH_MAX] = "";
02799    char ext_context[256] = "";
02800    char fmt[80];
02801    char *context;
02802    char ecodes[16] = "#";
02803    char tmp[1024] = "", *tmpptr;
02804    struct ast_vm_user *vmu;
02805    struct ast_vm_user svm;
02806    const char *category = NULL;
02807 
02808    ast_copy_string(tmp, ext, sizeof(tmp));
02809    ext = tmp;
02810    context = strchr(tmp, '@');
02811    if (context) {
02812       *context++ = '\0';
02813       tmpptr = strchr(context, '&');
02814    } else {
02815       tmpptr = strchr(ext, '&');
02816    }
02817 
02818    if (tmpptr)
02819       *tmpptr++ = '\0';
02820 
02821    category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
02822 
02823    if (option_debug > 2)
02824       ast_log(LOG_DEBUG, "Before find_user\n");
02825    if (!(vmu = find_user(&svm, context, ext))) {
02826       ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
02827       if (ast_test_flag(options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
02828          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
02829       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02830       return res;
02831    }
02832    /* Setup pre-file if appropriate */
02833    if (strcmp(vmu->context, "default"))
02834       snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
02835    else
02836       ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
02837    if (ast_test_flag(options, OPT_BUSY_GREETING)) {
02838       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "busy");
02839       snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
02840    } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
02841       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "unavail");
02842       snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
02843    }
02844    snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
02845    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "temp"))) {
02846       ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
02847       return -1;
02848    }
02849    RETRIEVE(tempfile, -1);
02850    if (ast_fileexists(tempfile, NULL, NULL) > 0)
02851       ast_copy_string(prefile, tempfile, sizeof(prefile));
02852    DISPOSE(tempfile, -1);
02853    /* It's easier just to try to make it than to check for its existence */
02854    create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
02855    create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp");
02856 
02857    /* Check current or macro-calling context for special extensions */
02858    if (ast_test_flag(vmu, VM_OPERATOR)) {
02859       if (!ast_strlen_zero(vmu->exit)) {
02860          if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
02861             strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02862             ouseexten = 1;
02863          }
02864       } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
02865          strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02866          ouseexten = 1;
02867       }
02868       else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
02869       strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02870       ousemacro = 1;
02871       }
02872    }
02873 
02874    if (!ast_strlen_zero(vmu->exit)) {
02875       if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
02876          strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
02877    } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
02878       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
02879    else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
02880       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
02881       ausemacro = 1;
02882    }
02883 
02884    /* Play the beginning intro if desired */
02885    if (!ast_strlen_zero(prefile)) {
02886 #ifdef ODBC_STORAGE
02887       int success = 
02888 #endif
02889          RETRIEVE(prefile, -1);
02890       if (ast_fileexists(prefile, NULL, NULL) > 0) {
02891          if (ast_streamfile(chan, prefile, chan->language) > -1) 
02892             res = ast_waitstream(chan, ecodes);
02893 #ifdef ODBC_STORAGE
02894          if (success == -1) {
02895             /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
02896             if (option_debug)
02897                ast_log(LOG_DEBUG, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
02898             store_file(prefile, vmu->mailbox, vmu->context, -1);
02899          }
02900 #endif
02901       } else {
02902          if (option_debug)
02903             ast_log(LOG_DEBUG, "%s doesn't exist, doing what we can\n", prefile);
02904          res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
02905       }
02906       DISPOSE(prefile, -1);
02907       if (res < 0) {
02908          if (option_debug)
02909             ast_log(LOG_DEBUG, "Hang up during prefile playback\n");
02910          free_user(vmu);
02911          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02912          return -1;
02913       }
02914    }
02915    if (res == '#') {
02916       /* On a '#' we skip the instructions */
02917       ast_set_flag(options, OPT_SILENT);
02918       res = 0;
02919    }
02920    if (!res && !ast_test_flag(options, OPT_SILENT)) {
02921       res = ast_stream_and_wait(chan, INTRO, chan->language, ecodes);
02922       if (res == '#') {
02923          ast_set_flag(options, OPT_SILENT);
02924          res = 0;
02925       }
02926    }
02927    if (res > 0)
02928       ast_stopstream(chan);
02929    /* Check for a '*' here in case the caller wants to escape from voicemail to something
02930     other than the operator -- an automated attendant or mailbox login for example */
02931    if (res == '*') {
02932       chan->exten[0] = 'a';
02933       chan->exten[1] = '\0';
02934       if (!ast_strlen_zero(vmu->exit)) {
02935          ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
02936       } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
02937          ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
02938       }
02939       chan->priority = 0;
02940       free_user(vmu);
02941       pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
02942       return 0;
02943    }
02944 
02945    /* Check for a '0' here */
02946    if (res == '0') {
02947    transfer:
02948       if (ouseexten || ousemacro) {
02949          chan->exten[0] = 'o';
02950          chan->exten[1] = '\0';
02951          if (!ast_strlen_zero(vmu->exit)) {
02952             ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
02953          } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
02954             ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
02955          }
02956          ast_play_and_wait(chan, "transfer");
02957          chan->priority = 0;
02958          free_user(vmu);
02959          pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
02960       }
02961       return 0;
02962    }
02963    if (res < 0) {
02964       free_user(vmu);
02965       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02966       return -1;
02967    }
02968    /* The meat of recording the message...  All the announcements and beeps have been played*/
02969    ast_copy_string(fmt, vmfmts, sizeof(fmt));
02970    if (!ast_strlen_zero(fmt)) {
02971       msgnum = 0;
02972 
02973 #ifdef IMAP_STORAGE
02974       /* Is ext a mailbox? */
02975       /* must open stream for this user to get info! */
02976       res = inboxcount(ext_context, &newmsgs, &oldmsgs);
02977       if (res < 0) {
02978          ast_log(LOG_NOTICE,"Can not leave voicemail, unable to count messages\n");
02979          return -1;
02980       }
02981       if (!(vms = get_vm_state_by_mailbox(ext,0))) {
02982       /*It is possible under certain circumstances that inboxcount did not create a vm_state when it was needed. This is a catchall which will
02983        * rarely be used*/
02984          if (!(vms = ast_calloc(1, sizeof(*vms)))) {
02985             ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
02986             return -1;
02987          }
02988          ast_copy_string(vms->imapuser, vmu->imapuser, sizeof(vms->imapuser));
02989          ast_copy_string(vms->username, ext, sizeof(vms->username));
02990          vms->mailstream = NIL;
02991          if (option_debug > 2)
02992             ast_log(LOG_DEBUG, "Copied %s to %s\n", vmu->imapuser, vms->imapuser);
02993          vms->updated=1;
02994          ast_copy_string(vms->curbox, mbox(0), sizeof(vms->curbox));
02995          init_vm_state(vms);
02996          vmstate_insert(vms);
02997          vms = get_vm_state_by_mailbox(ext,0);
02998       }
02999       vms->newmessages++;
03000       /* here is a big difference! We add one to it later */
03001       msgnum = newmsgs + oldmsgs;
03002       if (option_debug > 2)
03003          ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
03004       snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
03005       /* set variable for compatability */
03006       pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
03007 
03008       /* Check if mailbox is full */
03009       check_quota(vms, imapfolder);
03010       if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
03011          if (option_debug)
03012             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
03013          ast_play_and_wait(chan, "vm-mailboxfull");
03014          return -1;
03015       }
03016       if (option_debug > 2)
03017          ast_log(LOG_DEBUG, "Checking message number quota - mailbox has %d messages, maximum is set to %d\n",msgnum,vmu->maxmsg);
03018       if (msgnum >= vmu->maxmsg) {
03019          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
03020          if (!res)
03021             res = ast_waitstream(chan, "");
03022          ast_log(LOG_WARNING, "No more messages possible\n");
03023          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03024          goto leave_vm_out;
03025       }
03026 
03027       /* Check if we have exceeded maxmsg */
03028       if (msgnum >= vmu->maxmsg) {
03029          ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
03030          ast_play_and_wait(chan, "vm-mailboxfull");
03031          return -1;
03032       }
03033       /* here is a big difference! We add one to it later */
03034       if (option_debug > 2)
03035          ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
03036 #else
03037       if (count_messages(vmu, dir) >= vmu->maxmsg) {
03038          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
03039          if (!res)
03040             res = ast_waitstream(chan, "");
03041          ast_log(LOG_WARNING, "No more messages possible\n");
03042          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03043          goto leave_vm_out;
03044       }
03045 
03046 #endif
03047       snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
03048       txtdes = mkstemp(tmptxtfile);
03049       chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
03050       if (txtdes < 0) {
03051          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
03052          if (!res)
03053             res = ast_waitstream(chan, "");
03054          ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
03055          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03056          goto leave_vm_out;
03057       }
03058 
03059       /* Now play the beep once we have the message number for our next message. */
03060       if (res >= 0) {
03061          /* Unless we're *really* silent, try to send the beep */
03062          res = ast_stream_and_wait(chan, "beep", chan->language, "");
03063       }
03064             
03065       /* Store information */
03066       txt = fdopen(txtdes, "w+");
03067       if (txt) {
03068          get_date(date, sizeof(date));
03069          fprintf(txt, 
03070             ";\n"
03071             "; Message Information file\n"
03072             ";\n"
03073             "[message]\n"
03074             "origmailbox=%s\n"
03075             "context=%s\n"
03076             "macrocontext=%s\n"
03077             "exten=%s\n"
03078             "priority=%d\n"
03079             "callerchan=%s\n"
03080             "callerid=%s\n"
03081             "origdate=%s\n"
03082             "origtime=%ld\n"
03083             "category=%s\n",
03084             ext,
03085             chan->context,
03086             chan->macrocontext, 
03087             chan->exten,
03088             chan->priority,
03089             chan->name,
03090             ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
03091             date, (long)time(NULL),
03092             category ? category : ""); 
03093       } else
03094          ast_log(LOG_WARNING, "Error opening text file for output\n");
03095 #ifdef IMAP_STORAGE
03096       res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, vms);
03097 #else
03098       res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, NULL);
03099 #endif
03100 
03101       if (txt) {
03102          if (duration < vmminmessage) {
03103             fclose(txt);
03104             if (option_verbose > 2) 
03105                ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage);
03106             ast_filedelete(tmptxtfile, NULL);
03107             unlink(tmptxtfile);
03108          } else {
03109             fprintf(txt, "duration=%d\n", duration);
03110             fclose(txt);
03111             if (vm_lock_path(dir)) {
03112                ast_log(LOG_ERROR, "Couldn't lock directory %s.  Voicemail will be lost.\n", dir);
03113                /* Delete files */
03114                ast_filedelete(tmptxtfile, NULL);
03115                unlink(tmptxtfile);
03116             } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
03117                if (option_debug) 
03118                   ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
03119                unlink(tmptxtfile);
03120                ast_unlock_path(dir);
03121             } else {
03122                for (;;) {
03123                   make_file(fn, sizeof(fn), dir, msgnum);
03124                   if (!EXISTS(dir, msgnum, fn, NULL))
03125                      break;
03126                   msgnum++;
03127                }
03128 
03129                /* assign a variable with the name of the voicemail file */ 
03130 #ifndef IMAP_STORAGE
03131                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
03132 #else
03133                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
03134 #endif
03135 
03136                snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
03137                ast_filerename(tmptxtfile, fn, NULL);
03138                rename(tmptxtfile, txtfile);
03139 
03140                ast_unlock_path(dir);
03141                /* We must store the file first, before copying the message, because
03142                 * ODBC storage does the entire copy with SQL.
03143                 */
03144                if (ast_fileexists(fn, NULL, NULL) > 0) {
03145                   STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms);
03146                }
03147 
03148                /* Are there to be more recipients of this message? */
03149                while (tmpptr) {
03150                   struct ast_vm_user recipu, *recip;
03151                   char *exten, *context;
03152                
03153                   exten = strsep(&tmpptr, "&");
03154                   context = strchr(exten, '@');
03155                   if (context) {
03156                      *context = '\0';
03157                      context++;
03158                   }
03159                   if ((recip = find_user(&recipu, context, exten))) {
03160                      copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir);
03161                      free_user(recip);
03162                   }
03163                }
03164                /* Notification and disposal needs to happen after the copy, though. */
03165                if (ast_fileexists(fn, NULL, NULL)) {
03166                   notify_new_message(chan, vmu, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
03167                   DISPOSE(dir, msgnum);
03168                }
03169             }
03170          }
03171       }
03172       if (res == '0') {
03173          goto transfer;
03174       } else if (res > 0)
03175          res = 0;
03176 
03177       if (duration < vmminmessage)
03178          /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
03179          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03180       else
03181          pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
03182    } else
03183       ast_log(LOG_WARNING, "No format for saving voicemail?\n");
03184 leave_vm_out:
03185    free_user(vmu);
03186    
03187    return res;
03188 }

static int load_config ( void   )  [static]

Definition at line 7291 of file app_voicemail.c.

References adsifdn, adsisec, adsiver, append_mailbox(), apply_options_full(), ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_config_option(), ast_false(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log(), ast_malloc, ast_set2_flag, ast_set_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, ast_vm_user::context, dialcontext, emailbody, emaildateformat, emailsubject, emailtitle, exitcontext, ext_pass_cmd, externnotify, find_or_create(), free, free_user(), free_zone(), fromstring, globalflags, ast_variable::lineno, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_vm_user::mailcmd, MAX_NUM_CID_CONTEXTS, maxgreet, maxlogins, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, maxsilence, ast_variable::name, ast_variable::next, option_debug, pagerbody, pagerfromstring, pagersubject, populate_defaults(), s, saydurationminfo, SENDMAIL, ast_vm_user::serveremail, silencethreshold, skipms, smdi_iface, strsep(), users, userscontext, ast_variable::value, var, VM_ALLOCED, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_OPERATOR, VM_PBXSKIP, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, vmfmts, vmmaxmessage, vmminmessage, VOICEMAIL_CONFIG, and ast_vm_user::volgain.

07292 {
07293    struct ast_vm_user *cur;
07294    struct vm_zone *zcur;
07295    struct ast_config *cfg, *ucfg;
07296    char *cat;
07297    struct ast_variable *var;
07298    const char *notifystr = NULL;
07299    const char *smdistr = NULL;
07300    const char *astattach;
07301    const char *astsearch;
07302    const char *astsaycid;
07303    const char *send_voicemail;
07304 #ifdef IMAP_STORAGE
07305    const char *imap_server;
07306    const char *imap_port;
07307    const char *imap_flags;
07308    const char *imap_folder;
07309    const char *auth_user;
07310    const char *auth_password;
07311    const char *expunge_on_hangup;
07312 #endif
07313    const char *astcallop;
07314    const char *astreview;
07315    const char *asttempgreetwarn;
07316    const char *astskipcmd;
07317    const char *asthearenv;
07318    const char *astsaydurationinfo;
07319    const char *astsaydurationminfo;
07320    const char *silencestr;
07321    const char *maxmsgstr;
07322    const char *astdirfwd;
07323    const char *thresholdstr;
07324    const char *fmt;
07325    const char *astemail;
07326    const char *ucontext;
07327    const char *astmailcmd = SENDMAIL;
07328    const char *astforcename;
07329    const char *astforcegreet;
07330    const char *s;
07331    char *q,*stringp;
07332    const char *dialoutcxt = NULL;
07333    const char *callbackcxt = NULL;  
07334    const char *exitcxt = NULL;   
07335    const char *extpc;
07336    const char *emaildateformatstr;
07337    const char *volgainstr;
07338    int x;
07339    int tmpadsi[4];
07340 
07341    cfg = ast_config_load(VOICEMAIL_CONFIG);
07342 
07343    AST_LIST_LOCK(&users);
07344    while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
07345       ast_set_flag(cur, VM_ALLOCED);
07346       free_user(cur);
07347    }
07348 
07349    AST_LIST_LOCK(&zones);
07350    while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 
07351       free_zone(zcur);
07352    AST_LIST_UNLOCK(&zones);
07353 
07354    memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
07355 
07356    if (cfg) {
07357       /* General settings */
07358 
07359       if (!(ucontext = ast_variable_retrieve(cfg, "general", "userscontext")))
07360          ucontext = "default";
07361       ast_copy_string(userscontext, ucontext, sizeof(userscontext));
07362       /* Attach voice message to mail message ? */
07363       if (!(astattach = ast_variable_retrieve(cfg, "general", "attach"))) 
07364          astattach = "yes";
07365       ast_set2_flag((&globalflags), ast_true(astattach), VM_ATTACH); 
07366 
07367       if (!(astsearch = ast_variable_retrieve(cfg, "general", "searchcontexts")))
07368          astsearch = "no";
07369       ast_set2_flag((&globalflags), ast_true(astsearch), VM_SEARCH);
07370 
07371       volgain = 0.0;
07372       if ((volgainstr = ast_variable_retrieve(cfg, "general", "volgain")))
07373          sscanf(volgainstr, "%lf", &volgain);
07374 
07375 #ifdef ODBC_STORAGE
07376       strcpy(odbc_database, "asterisk");
07377       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
07378          ast_copy_string(odbc_database, thresholdstr, sizeof(odbc_database));
07379       }
07380       strcpy(odbc_table, "voicemessages");
07381       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbctable"))) {
07382          ast_copy_string(odbc_table, thresholdstr, sizeof(odbc_table));
07383       }
07384 #endif      
07385       /* Mail command */
07386       strcpy(mailcmd, SENDMAIL);
07387       if ((astmailcmd = ast_variable_retrieve(cfg, "general", "mailcmd")))
07388          ast_copy_string(mailcmd, astmailcmd, sizeof(mailcmd)); /* User setting */
07389 
07390       maxsilence = 0;
07391       if ((silencestr = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
07392          maxsilence = atoi(silencestr);
07393          if (maxsilence > 0)
07394             maxsilence *= 1000;
07395       }
07396       
07397       if (!(maxmsgstr = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
07398          maxmsg = MAXMSG;
07399       } else {
07400          maxmsg = atoi(maxmsgstr);
07401          if (maxmsg <= 0) {
07402             ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", maxmsgstr, MAXMSG);
07403             maxmsg = MAXMSG;
07404          } else if (maxmsg > MAXMSGLIMIT) {
07405             ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, maxmsgstr);
07406             maxmsg = MAXMSGLIMIT;
07407          }
07408       }
07409 
07410       /* Load date format config for voicemail mail */
07411       if ((emaildateformatstr = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
07412          ast_copy_string(emaildateformat, emaildateformatstr, sizeof(emaildateformat));
07413       }
07414 
07415       /* External password changing command */
07416       if ((extpc = ast_variable_retrieve(cfg, "general", "externpass"))) {
07417          ast_copy_string(ext_pass_cmd,extpc,sizeof(ext_pass_cmd));
07418       }
07419 #ifdef IMAP_STORAGE
07420       /* IMAP server address */
07421       if ((imap_server = ast_variable_retrieve(cfg, "general", "imapserver"))) {
07422          ast_copy_string(imapserver, imap_server, sizeof(imapserver));
07423       } else {
07424          ast_copy_string(imapserver,"localhost", sizeof(imapserver));
07425       }
07426       /* IMAP server port */
07427       if ((imap_port = ast_variable_retrieve(cfg, "general", "imapport"))) {
07428          ast_copy_string(imapport, imap_port, sizeof(imapport));
07429       } else {
07430          ast_copy_string(imapport,"143", sizeof(imapport));
07431       }
07432       /* IMAP server flags */
07433       if ((imap_flags = ast_variable_retrieve(cfg, "general", "imapflags"))) {
07434          ast_copy_string(imapflags, imap_flags, sizeof(imapflags));
07435       }
07436       /* IMAP server master username */
07437       if ((auth_user = ast_variable_retrieve(cfg, "general", "authuser"))) {
07438          ast_copy_string(authuser, auth_user, sizeof(authuser));
07439       }
07440       /* IMAP server master password */
07441       if ((auth_password = ast_variable_retrieve(cfg, "general", "authpassword"))) {
07442          ast_copy_string(authpassword, auth_password, sizeof(authpassword));
07443       }
07444       /* Expunge on exit */
07445       if ((expunge_on_hangup = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) {
07446          if (ast_false(expunge_on_hangup))
07447             expungeonhangup = 0;
07448          else
07449             expungeonhangup = 1;
07450       } else {
07451          expungeonhangup = 1;
07452       }
07453       /* IMAP voicemail folder */
07454       if ((imap_folder = ast_variable_retrieve(cfg, "general", "imapfolder"))) {
07455          ast_copy_string(imapfolder, imap_folder, sizeof(imapfolder));
07456       } else {
07457          ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
07458       }
07459 #endif
07460       /* External voicemail notify application */
07461       
07462       if ((notifystr = ast_variable_retrieve(cfg, "general", "externnotify"))) {
07463          ast_copy_string(externnotify, notifystr, sizeof(externnotify));
07464          if (option_debug > 2)
07465             ast_log(LOG_DEBUG, "found externnotify: %s\n", externnotify);
07466          if (!strcasecmp(externnotify, "smdi")) {
07467             if (option_debug)
07468                ast_log(LOG_DEBUG, "Using SMDI for external voicemail notification\n");
07469             if ((smdistr = ast_variable_retrieve(cfg, "general", "smdiport"))) {
07470                smdi_iface = ast_smdi_interface_find(smdistr);
07471             } else {
07472                if (option_debug)
07473                   ast_log(LOG_DEBUG, "No SMDI interface set, trying default (/dev/ttyS0)\n");
07474                smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
07475             }
07476 
07477             if (!smdi_iface) {
07478                ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling external voicemail notification\n");
07479                externnotify[0] = '\0';
07480             } else {
07481                if (option_debug > 2)
07482                   ast_log(LOG_DEBUG, "Using SMDI port %s\n", smdi_iface->name);
07483             }
07484          }
07485       } else {
07486          externnotify[0] = '\0';
07487       }
07488 
07489       /* Silence treshold */
07490       silencethreshold = 256;
07491       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "silencethreshold")))
07492          silencethreshold = atoi(thresholdstr);
07493       
07494       if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail"))) 
07495          astemail = ASTERISK_USERNAME;
07496       ast_copy_string(serveremail, astemail, sizeof(serveremail));
07497       
07498       vmmaxmessage = 0;
07499       if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
07500          if (sscanf(s, "%d", &x) == 1) {
07501             vmmaxmessage = x;
07502          } else {
07503             ast_log(LOG_WARNING, "Invalid max message time length\n");
07504          }
07505       }
07506 
07507       vmminmessage = 0;
07508       if ((s = ast_variable_retrieve(cfg, "general", "minmessage"))) {
07509          if (sscanf(s, "%d", &x) == 1) {
07510             vmminmessage = x;
07511             if (maxsilence <= vmminmessage)
07512                ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
07513          } else {
07514             ast_log(LOG_WARNING, "Invalid min message time length\n");
07515          }
07516       }
07517       fmt = ast_variable_retrieve(cfg, "general", "format");
07518       if (!fmt)
07519          fmt = "wav";   
07520       ast_copy_string(vmfmts, fmt, sizeof(vmfmts));
07521 
07522       skipms = 3000;
07523       if ((s = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
07524          if (sscanf(s, "%d", &x) == 1) {
07525             maxgreet = x;
07526          } else {
07527             ast_log(LOG_WARNING, "Invalid max message greeting length\n");
07528          }
07529       }
07530 
07531       if ((s = ast_variable_retrieve(cfg, "general", "skipms"))) {
07532          if (sscanf(s, "%d", &x) == 1) {
07533             skipms = x;
07534          } else {
07535             ast_log(LOG_WARNING, "Invalid skipms value\n");
07536          }
07537       }
07538 
07539       maxlogins = 3;
07540       if ((s = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
07541          if (sscanf(s, "%d", &x) == 1) {
07542             maxlogins = x;
07543          } else {
07544             ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
07545          }
07546       }
07547 
07548       /* Force new user to record name ? */
07549       if (!(astforcename = ast_variable_retrieve(cfg, "general", "forcename"))) 
07550          astforcename = "no";
07551       ast_set2_flag((&globalflags), ast_true(astforcename), VM_FORCENAME);
07552 
07553       /* Force new user to record greetings ? */
07554       if (!(astforcegreet = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 
07555          astforcegreet = "no";
07556       ast_set2_flag((&globalflags), ast_true(astforcegreet), VM_FORCEGREET);
07557 
07558       if ((s = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))){
07559          if (option_debug > 2)
07560             ast_log(LOG_DEBUG,"VM_CID Internal context string: %s\n",s);
07561          stringp = ast_strdupa(s);
07562          for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
07563             if (!ast_strlen_zero(stringp)) {
07564                q = strsep(&stringp,",");
07565                while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
07566                   q++;
07567                ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
07568                if (option_debug > 2)
07569                   ast_log(LOG_DEBUG,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
07570             } else {
07571                cidinternalcontexts[x][0] = '\0';
07572             }
07573          }
07574       }
07575       if (!(astreview = ast_variable_retrieve(cfg, "general", "review"))){
07576          if (option_debug)
07577             ast_log(LOG_DEBUG,"VM Review Option disabled globally\n");
07578          astreview = "no";
07579       }
07580       ast_set2_flag((&globalflags), ast_true(astreview), VM_REVIEW); 
07581 
07582       /*Temperary greeting reminder */
07583       if (!(asttempgreetwarn = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) {
07584          if (option_debug)
07585             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option disabled globally\n");
07586          asttempgreetwarn = "no";
07587       } else {
07588          if (option_debug)
07589             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option enabled globally\n");
07590       }
07591       ast_set2_flag((&globalflags), ast_true(asttempgreetwarn), VM_TEMPGREETWARN);
07592 
07593       if (!(astcallop = ast_variable_retrieve(cfg, "general", "operator"))){
07594          if (option_debug)
07595             ast_log(LOG_DEBUG,"VM Operator break disabled globally\n");
07596          astcallop = "no";
07597       }
07598       ast_set2_flag((&globalflags), ast_true(astcallop), VM_OPERATOR);  
07599 
07600       if (!(astsaycid = ast_variable_retrieve(cfg, "general", "saycid"))) {
07601          if (option_debug)
07602             ast_log(LOG_DEBUG,"VM CID Info before msg disabled globally\n");
07603          astsaycid = "no";
07604       } 
07605       ast_set2_flag((&globalflags), ast_true(astsaycid), VM_SAYCID); 
07606 
07607       if (!(send_voicemail = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){
07608          if (option_debug)
07609             ast_log(LOG_DEBUG,"Send Voicemail msg disabled globally\n");
07610          send_voicemail = "no";
07611       }
07612       ast_set2_flag((&globalflags), ast_true(send_voicemail), VM_SVMAIL);
07613    
07614       if (!(asthearenv = ast_variable_retrieve(cfg, "general", "envelope"))) {
07615          if (option_debug)
07616             ast_log(LOG_DEBUG,"ENVELOPE before msg enabled globally\n");
07617          asthearenv = "yes";
07618       }
07619       ast_set2_flag((&globalflags), ast_true(asthearenv), VM_ENVELOPE); 
07620 
07621       if (!(astsaydurationinfo = ast_variable_retrieve(cfg, "general", "sayduration"))) {
07622          if (option_debug)
07623             ast_log(LOG_DEBUG,"Duration info before msg enabled globally\n");
07624          astsaydurationinfo = "yes";
07625       }
07626       ast_set2_flag((&globalflags), ast_true(astsaydurationinfo), VM_SAYDURATION);  
07627 
07628       saydurationminfo = 2;
07629       if ((astsaydurationminfo = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
07630          if (sscanf(astsaydurationminfo, "%d", &x) == 1) {
07631             saydurationminfo = x;
07632          } else {
07633             ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
07634          }
07635       }
07636 
07637       if (!(astskipcmd = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
07638          if (option_debug)
07639             ast_log(LOG_DEBUG,"We are not going to skip to the next msg after save/delete\n");
07640          astskipcmd = "no";
07641       }
07642       ast_set2_flag((&globalflags), ast_true(astskipcmd), VM_SKIPAFTERCMD);
07643 
07644       if ((dialoutcxt = ast_variable_retrieve(cfg, "general", "dialout"))) {
07645          ast_copy_string(dialcontext, dialoutcxt, sizeof(dialcontext));
07646          if (option_debug)
07647             ast_log(LOG_DEBUG, "found dialout context: %s\n", dialcontext);
07648       } else {
07649          dialcontext[0] = '\0';  
07650       }
07651       
07652       if ((callbackcxt = ast_variable_retrieve(cfg, "general", "callback"))) {
07653          ast_copy_string(callcontext, callbackcxt, sizeof(callcontext));
07654          if (option_debug)
07655             ast_log(LOG_DEBUG, "found callback context: %s\n", callcontext);
07656       } else {
07657          callcontext[0] = '\0';
07658       }
07659 
07660       if ((exitcxt = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
07661          ast_copy_string(exitcontext, exitcxt, sizeof(exitcontext));
07662          if (option_debug)
07663             ast_log(LOG_DEBUG, "found operator context: %s\n", exitcontext);
07664       } else {
07665          exitcontext[0] = '\0';
07666       }
07667 
07668       if (!(astdirfwd = ast_variable_retrieve(cfg, "general", "usedirectory"))) 
07669          astdirfwd = "no";
07670       ast_set2_flag((&globalflags), ast_true(astdirfwd), VM_DIRECFORWARD); 
07671       if ((ucfg = ast_config_load("users.conf"))) {   
07672          for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
07673             if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
07674                continue;
07675             if ((cur = find_or_create(userscontext, cat))) {
07676                populate_defaults(cur);
07677                apply_options_full(cur, ast_variable_browse(ucfg, cat));
07678                ast_copy_string(cur->context, userscontext, sizeof(cur->context));
07679             }
07680          }
07681          ast_config_destroy(ucfg);
07682       }
07683       cat = ast_category_browse(cfg, NULL);
07684       while (cat) {
07685          if (strcasecmp(cat, "general")) {
07686             var = ast_variable_browse(cfg, cat);
07687             if (strcasecmp(cat, "zonemessages")) {
07688                /* Process mailboxes in this context */
07689                while (var) {
07690                   append_mailbox(cat, var->name, var->value);
07691                   var = var->next;
07692                }
07693             } else {
07694                /* Timezones in this context */
07695                while (var) {
07696                   struct vm_zone *z;
07697                   if ((z = ast_malloc(sizeof(*z)))) {
07698                      char *msg_format, *timezone;
07699                      msg_format = ast_strdupa(var->value);
07700                      timezone = strsep(&msg_format, "|");
07701                      if (msg_format) {
07702                         ast_copy_string(z->name, var->name, sizeof(z->name));
07703                         ast_copy_string(z->timezone, timezone, sizeof(z->timezone));
07704                         ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
07705                         AST_LIST_LOCK(&zones);
07706                         AST_LIST_INSERT_HEAD(&zones, z, list);
07707                         AST_LIST_UNLOCK(&zones);
07708                      } else {
07709                         ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
07710                         free(z);
07711                      }
07712                   } else {
07713                      free(z);
07714                      AST_LIST_UNLOCK(&users);
07715                      ast_config_destroy(cfg);
07716                      return -1;
07717                   }
07718                   var = var->next;
07719                }
07720             }
07721          }
07722          cat = ast_category_browse(cfg, cat);
07723       }
07724       memset(fromstring,0,sizeof(fromstring));
07725       memset(pagerfromstring,0,sizeof(pagerfromstring));
07726       memset(emailtitle,0,sizeof(emailtitle));
07727       strcpy(charset, "ISO-8859-1");
07728       if (emailbody) {
07729          free(emailbody);
07730          emailbody = NULL;
07731       }
07732       if (emailsubject) {
07733          free(emailsubject);
07734          emailsubject = NULL;
07735       }
07736       if (pagerbody) {
07737          free(pagerbody);
07738          pagerbody = NULL;
07739       }
07740       if (pagersubject) {
07741          free(pagersubject);
07742          pagersubject = NULL;
07743       }
07744       if ((s = ast_variable_retrieve(cfg, "general", "pbxskip")))
07745          ast_set2_flag((&globalflags), ast_true(s), VM_PBXSKIP);
07746       if ((s = ast_variable_retrieve(cfg, "general", "fromstring")))
07747          ast_copy_string(fromstring,s,sizeof(fromstring));
07748       if ((s = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
07749          ast_copy_string(pagerfromstring,s,sizeof(pagerfromstring));
07750       if ((s = ast_variable_retrieve(cfg, "general", "charset")))
07751          ast_copy_string(charset,s,sizeof(charset));
07752       if ((s = ast_variable_retrieve(cfg, "general", "adsifdn"))) {
07753          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
07754          for (x = 0; x < 4; x++) {
07755             memcpy(&adsifdn[x], &tmpadsi[x], 1);
07756          }
07757       }
07758       if ((s = ast_variable_retrieve(cfg, "general", "adsisec"))) {
07759          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
07760          for (x = 0; x < 4; x++) {
07761             memcpy(&adsisec[x], &tmpadsi[x], 1);
07762          }
07763       }
07764       if ((s = ast_variable_retrieve(cfg, "general", "adsiver")))
07765          if (atoi(s)) {
07766             adsiver = atoi(s);
07767          }
07768       if ((s = ast_variable_retrieve(cfg, "general", "emailtitle"))) {
07769          ast_log(LOG_NOTICE, "Keyword 'emailtitle' is DEPRECATED, please use 'emailsubject' instead.\n");
07770          ast_copy_string(emailtitle,s,sizeof(emailtitle));
07771       }
07772       if ((s = ast_variable_retrieve(cfg, "general", "emailsubject")))
07773          emailsubject = ast_strdup(s);
07774       if ((s = ast_variable_retrieve(cfg, "general", "emailbody"))) {
07775          char *tmpread, *tmpwrite;
07776          emailbody = ast_strdup(s);
07777 
07778          /* substitute strings \t and \n into the appropriate characters */
07779          tmpread = tmpwrite = emailbody;
07780          while ((tmpwrite = strchr(tmpread,'\\'))) {
07781             switch (tmpwrite[1]) {
07782             case 'r':
07783                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07784                *tmpwrite = '\r';
07785                break;
07786             case 'n':
07787                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07788                *tmpwrite = '\n';
07789                break;
07790             case 't':
07791                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07792                *tmpwrite = '\t';
07793                break;
07794             default:
07795                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
07796             }
07797             tmpread = tmpwrite + 1;
07798          }
07799       }
07800       if ((s = ast_variable_retrieve(cfg, "general", "pagersubject")))
07801          pagersubject = ast_strdup(s);
07802       if ((s = ast_variable_retrieve(cfg, "general", "pagerbody"))) {
07803          char *tmpread, *tmpwrite;
07804          pagerbody = ast_strdup(s);
07805 
07806          /* substitute strings \t and \n into the appropriate characters */
07807          tmpread = tmpwrite = pagerbody;
07808          while ((tmpwrite = strchr(tmpread, '\\'))) {
07809             switch (tmpwrite[1]) {
07810             case 'r':
07811                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07812                *tmpwrite = '\r';
07813                break;
07814             case 'n':
07815                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07816                *tmpwrite = '\n';
07817                break;
07818             case 't':
07819                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07820                *tmpwrite = '\t';
07821                break;
07822             default:
07823                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
07824             }
07825             tmpread = tmpwrite + 1;
07826          }
07827       }
07828       AST_LIST_UNLOCK(&users);
07829       ast_config_destroy(cfg);
07830       return 0;
07831    } else {
07832       AST_LIST_UNLOCK(&users);
07833       ast_log(LOG_WARNING, "Failed to load configuration file.\n");
07834       return 0;
07835    }
07836 }

static int load_module ( void   )  [static]

static int make_dir ( char *  dest,
int  len,
const char *  context,
const char *  ext,
const char *  folder 
) [static]

Definition at line 863 of file app_voicemail.c.

References VM_SPOOL_DIR.

Referenced by copy_message(), create_dirpath(), and notify_new_message().

00864 {
00865    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
00866 }

static void make_email_file ( FILE *  p,
char *  srcemail,
struct ast_vm_user vmu,
int  msgnum,
char *  context,
char *  mailbox,
char *  cidnum,
char *  cidname,
char *  attach,
char *  format,
int  duration,
int  attach_user_voicemail,
struct ast_channel chan,
const char *  category,
int  imap 
) [static]

Definition at line 1770 of file app_voicemail.c.

References ast_channel_alloc(), ast_channel_free(), ast_log(), ast_random(), ast_safe_system(), AST_STATE_DOWN, ast_strlen_zero(), ast_test_flag, base_encode(), charset, ast_vm_user::context, create_dirpath(), ast_vm_user::email, emailbody, emaildateformat, emailsubject, emailtitle, ENDL, fromstring, ast_vm_user::fullname, globalflags, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, my_umask, option_debug, pbx_substitute_variables_helper(), prep_email_sub_vars(), ast_channel::priority, quote(), VM_PBXSKIP, vmu_tm(), VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.

Referenced by sendmail().

01771 {
01772    char date[256];
01773    char host[MAXHOSTNAMELEN] = "";
01774    char who[256];
01775    char bound[256];
01776    char fname[256];
01777    char dur[256];
01778    char tmpcmd[256];
01779    struct tm tm;
01780    char *passdata2;
01781    size_t len_passdata;
01782 #ifdef IMAP_STORAGE
01783 #define ENDL "\r\n"
01784 #else
01785 #define ENDL "\n"
01786 #endif
01787 
01788    gethostname(host, sizeof(host) - 1);
01789    if (strchr(srcemail, '@'))
01790       ast_copy_string(who, srcemail, sizeof(who));
01791    else {
01792       snprintf(who, sizeof(who), "%s@%s", srcemail, host);
01793    }
01794    snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
01795    strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
01796    fprintf(p, "Date: %s" ENDL, date);
01797 
01798    /* Set date format for voicemail mail */
01799    strftime(date, sizeof(date), emaildateformat, &tm);
01800 
01801    if (*fromstring) {
01802       struct ast_channel *ast;
01803       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
01804          char *passdata;
01805          int vmlen = strlen(fromstring)*3 + 200;
01806          if ((passdata = alloca(vmlen))) {
01807             memset(passdata, 0, vmlen);
01808             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
01809             pbx_substitute_variables_helper(ast, fromstring, passdata, vmlen);
01810             len_passdata = strlen(passdata) * 2 + 3;
01811             passdata2 = alloca(len_passdata);
01812             fprintf(p, "From: %s <%s>" ENDL, quote(passdata, passdata2, len_passdata), who);
01813          } else
01814             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01815          ast_channel_free(ast);
01816       } else
01817          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01818    } else
01819       fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
01820    len_passdata = strlen(vmu->fullname) * 2 + 3;
01821    passdata2 = alloca(len_passdata);
01822    fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata), vmu->email);
01823    if (emailsubject) {
01824       struct ast_channel *ast;
01825       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
01826          char *passdata;
01827          int vmlen = strlen(emailsubject)*3 + 200;
01828          if ((passdata = alloca(vmlen))) {
01829             memset(passdata, 0, vmlen);
01830             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
01831             pbx_substitute_variables_helper(ast, emailsubject, passdata, vmlen);
01832             fprintf(p, "Subject: %s" ENDL, passdata);
01833          } else
01834             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01835          ast_channel_free(ast);
01836       } else
01837          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01838    } else   if (*emailtitle) {
01839       fprintf(p, emailtitle, msgnum + 1, mailbox) ;
01840       fprintf(p, ENDL) ;
01841    } else if (ast_test_flag((&globalflags), VM_PBXSKIP))
01842       fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
01843    else
01844       fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
01845    fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host);
01846    if (imap) {
01847       /* additional information needed for IMAP searching */
01848       fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
01849       /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */
01850       fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring);
01851       fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context);
01852       fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
01853       fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority);
01854       fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name);
01855       fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, cidnum);
01856       fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, cidname);
01857       fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
01858       if (!ast_strlen_zero(category))
01859          fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category);
01860       fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date);
01861       fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL));
01862    }
01863    if (!ast_strlen_zero(cidnum))
01864       fprintf(p, "X-Asterisk-CallerID: %s" ENDL, cidnum);
01865    if (!ast_strlen_zero(cidname))
01866       fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, cidname);
01867    fprintf(p, "MIME-Version: 1.0" ENDL);
01868    if (attach_user_voicemail) {
01869       /* Something unique. */
01870       snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random());
01871 
01872       fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
01873       fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
01874       fprintf(p, "--%s" ENDL, bound);
01875    }
01876    fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
01877    if (emailbody) {
01878       struct ast_channel *ast;
01879       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
01880          char *passdata;
01881          int vmlen = strlen(emailbody)*3 + 200;
01882          if ((passdata = alloca(vmlen))) {
01883             memset(passdata, 0, vmlen);
01884             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
01885             pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen);
01886             fprintf(p, "%s" ENDL, passdata);
01887          } else
01888             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01889          ast_channel_free(ast);
01890       } else
01891          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01892    } else {
01893       fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a %s long message (number %d)" ENDL
01894 
01895       "in mailbox %s from %s, on %s so you might" ENDL
01896       "want to check it when you get a chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, 
01897       dur, msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
01898    }
01899    if (attach_user_voicemail) {
01900       /* Eww. We want formats to tell us their own MIME type */
01901       char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
01902       char tmpdir[256], newtmp[256];
01903       int tmpfd = -1;
01904    
01905       if (vmu->volgain < -.001 || vmu->volgain > .001) {
01906          create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
01907          snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
01908          tmpfd = mkstemp(newtmp);
01909          chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
01910          if (option_debug > 2)
01911             ast_log(LOG_DEBUG, "newtmp: %s\n", newtmp);
01912          if (tmpfd > -1) {
01913             snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
01914             ast_safe_system(tmpcmd);
01915             attach = newtmp;
01916             if (option_debug > 2)
01917                ast_log(LOG_DEBUG, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
01918          }
01919       }
01920       fprintf(p, "--%s" ENDL, bound);
01921       fprintf(p, "Content-Type: %s%s; name=\"msg%04d.%s\"" ENDL, ctype, format, msgnum + 1, format);
01922       fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
01923       fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
01924       fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"" ENDL ENDL, msgnum + 1, format);
01925       snprintf(fname, sizeof(fname), "%s.%s", attach, format);
01926       base_encode(fname, p);
01927       fprintf(p, ENDL "--%s--" ENDL "." ENDL, bound);
01928       if (tmpfd > -1) {
01929          unlink(fname);
01930          close(tmpfd);
01931          unlink(newtmp);
01932       }
01933    }
01934 #undef ENDL
01935 }

static int make_file ( char *  dest,
int  len,
char *  dir,
int  num 
) [static]

Definition at line 899 of file app_voicemail.c.

Referenced by advanced_options(), close_mailbox(), copy_message(), last_message_index(), leave_voicemail(), notify_new_message(), play_message(), resequence_mailbox(), save_to_folder(), vm_execmain(), and vm_forwardoptions().

00900 {
00901    return snprintf(dest, len, "%s/msg%04d", dir, num);
00902 }

static const char* mbox ( int  id  )  [static]

Definition at line 2107 of file app_voicemail.c.

Referenced by adsi_load_vmail(), copy_message(), get_folder(), and save_to_folder().

02108 {
02109    static const char *msgs[] = {
02110       "INBOX",
02111       "Old",
02112       "Work",
02113       "Family",
02114       "Friends",
02115       "Cust1",
02116       "Cust2",
02117       "Cust3",
02118       "Cust4",
02119       "Cust5",
02120    };
02121    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "Unknown";
02122 }

static int messagecount ( const char *  context,
const char *  mailbox,
const char *  folder 
) [static]

Definition at line 2629 of file app_voicemail.c.

References __has_voicemail().

Referenced by load_module().

02630 {
02631    return __has_voicemail(context, mailbox, folder, 0);
02632 }

static int notify_new_message ( struct ast_channel chan,
struct ast_vm_user vmu,
int  msgnum,
long  duration,
char *  fmt,
char *  cidnum,
char *  cidname 
) [static]

Definition at line 3895 of file app_voicemail.c.

References ast_app_has_voicemail(), ast_app_inboxcount(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::attachfmt, ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::email, EVENT_FLAG_CALL, globalflags, LOG_WARNING, ast_vm_user::mailbox, make_dir(), make_file(), manager_event(), ast_vm_user::pager, pbx_builtin_getvar_helper(), RETRIEVE, run_externnotify(), sendmail(), sendpage(), ast_vm_user::serveremail, strsep(), VM_ATTACH, and VM_DELETE.

Referenced by copy_message(), and leave_voicemail().

03896 {
03897    char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
03898    int newmsgs = 0, oldmsgs = 0;
03899    const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
03900 
03901    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
03902    make_file(fn, sizeof(fn), todir, msgnum);
03903    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
03904 
03905    if (!ast_strlen_zero(vmu->attachfmt)) {
03906       if (strstr(fmt, vmu->attachfmt)) {
03907          fmt = vmu->attachfmt;
03908       } else {
03909          ast_log(LOG_WARNING, "Attachment format '%s' is not one of the recorded formats '%s'.  Falling back to default format for '%s@%s'.\n", vmu->attachfmt, fmt, vmu->mailbox, vmu->context);
03910       }
03911    }
03912 
03913    /* Attach only the first format */
03914    fmt = ast_strdupa(fmt);
03915    stringp = fmt;
03916    strsep(&stringp, "|");
03917 
03918    if (!ast_strlen_zero(vmu->email)) {
03919       int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
03920       char *myserveremail = serveremail;
03921       attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
03922       if (!ast_strlen_zero(vmu->serveremail))
03923          myserveremail = vmu->serveremail;
03924       
03925       if (attach_user_voicemail)
03926          RETRIEVE(todir, msgnum);
03927 
03928       /*XXX possible imap issue, should category be NULL XXX*/
03929       sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
03930 
03931       if (attach_user_voicemail)
03932          DISPOSE(todir, msgnum);
03933    }
03934 
03935    if (!ast_strlen_zero(vmu->pager)) {
03936       char *myserveremail = serveremail;
03937       if (!ast_strlen_zero(vmu->serveremail))
03938          myserveremail = vmu->serveremail;
03939       sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu, category);
03940    }
03941 
03942    if (ast_test_flag(vmu, VM_DELETE)) {
03943       DELETE(todir, msgnum, fn);
03944    }
03945 
03946 #ifdef IMAP_STORAGE
03947    DELETE(todir, msgnum, fn);
03948 #endif
03949    /* Leave voicemail for someone */
03950    if (ast_app_has_voicemail(ext_context, NULL)) {
03951       ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
03952    }
03953    manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s@%s\r\nWaiting: %d\r\nNew: %d\r\nOld: %d\r\n", vmu->mailbox, vmu->context, ast_app_has_voicemail(ext_context, NULL), newmsgs, oldmsgs);
03954    run_externnotify(vmu->context, vmu->mailbox);
03955    return 0;
03956 }

static int ochar ( struct baseio bio,
int  c,
FILE *  so 
) [static]

Definition at line 1609 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

01610 {
01611    if (bio->linelength>=BASELINELEN) {
01612       if (fputs(eol,so)==EOF)
01613          return -1;
01614 
01615       bio->linelength= 0;
01616    }
01617 
01618    if (putc(((unsigned char)c),so)==EOF)
01619       return -1;
01620 
01621    bio->linelength++;
01622 
01623    return 1;
01624 }

static int open_mailbox ( struct vm_state vms,
struct ast_vm_user vmu,
int  box 
) [static]

Definition at line 4795 of file app_voicemail.c.

References ast_log(), ast_vm_user::context, count_messages(), create_dirpath(), vm_state::curbox, vm_state::curdir, last_message_index(), vm_state::lastmsg, LOG_NOTICE, resequence_mailbox(), vm_state::username, and vm_state::vmbox.

Referenced by vm_execmain().

04796 {
04797    int res = 0;
04798    int count_msg, last_msg;
04799 
04800    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
04801    
04802    /* Rename the member vmbox HERE so that we don't try to return before
04803     * we know what's going on.
04804     */
04805    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
04806    
04807    /* Faster to make the directory than to check if it exists. */
04808    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
04809 
04810    count_msg = count_messages(vmu, vms->curdir);
04811    if (count_msg < 0)
04812       return count_msg;
04813    else
04814       vms->lastmsg = count_msg - 1;
04815 
04816    /*
04817    The following test is needed in case sequencing gets messed up.
04818    There appears to be more than one way to mess up sequence, so
04819    we will not try to find all of the root causes--just fix it when
04820    detected.
04821    */
04822 
04823    last_msg = last_message_index(vmu, vms->curdir);
04824    if (last_msg < 0)
04825       return last_msg;
04826    else if (vms->lastmsg != last_msg)
04827    {
04828       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
04829       res = resequence_mailbox(vmu, vms->curdir);
04830       if (res)
04831          return res;
04832    }
04833 
04834    return 0;
04835 }

static int play_message ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms 
) [static]

Definition at line 4560 of file app_voicemail.c.

References adsi_message(), ast_config_destroy(), ast_config_load(), AST_DIGIT_ANY, ast_log(), ast_say_number(), ast_strdupa, ast_test_flag, ast_variable_retrieve(), vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::fn2, vm_state::heard, vm_state::lastmsg, LOG_WARNING, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, VM_ENVELOPE, VM_SAYCID, VM_SAYDURATION, wait_file(), and wait_file2().

Referenced by vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_it(), vm_browse_messages_pt(), and vm_execmain().

04561 {
04562    int res = 0;
04563    char filename[256], *cid;
04564    const char *origtime, *context, *category, *duration;
04565    struct ast_config *msg_cfg;
04566 
04567    vms->starting = 0; 
04568    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
04569    adsi_message(chan, vms);
04570    if (!vms->curmsg)
04571       res = wait_file2(chan, vms, "vm-first");  /* "First" */
04572    else if (vms->curmsg == vms->lastmsg)
04573       res = wait_file2(chan, vms, "vm-last");      /* "last" */
04574    if (!res) {
04575       /* POLISH syntax */
04576       if (!strcasecmp(chan->language, "pl")) { 
04577          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
04578             int ten, one;
04579             char nextmsg[256];
04580             ten = (vms->curmsg + 1) / 10;
04581             one = (vms->curmsg + 1) % 10;
04582             
04583             if (vms->curmsg < 20) {
04584                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
04585                res = wait_file2(chan, vms, nextmsg);
04586             } else {
04587                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
04588                res = wait_file2(chan, vms, nextmsg);
04589                if (one > 0) {
04590                   if (!res) {
04591                      snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
04592                      res = wait_file2(chan, vms, nextmsg);
04593                   }
04594                }
04595             }
04596          }
04597          if (!res)
04598             res = wait_file2(chan, vms, "vm-message");
04599       } else {
04600          if (!strcasecmp(chan->language, "se")) /* SWEDISH syntax */
04601             res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
04602          else /* DEFAULT syntax */
04603             res = wait_file2(chan, vms, "vm-message");
04604          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
04605             if (!res)
04606                res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
04607          }
04608       }
04609    }
04610 
04611    /* Retrieve info from VM attribute file */
04612    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
04613    snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
04614    RETRIEVE(vms->curdir, vms->curmsg);
04615    msg_cfg = ast_config_load(filename);
04616    if (!msg_cfg) {
04617       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
04618       return 0;
04619    }
04620 
04621    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
04622       ast_log(LOG_WARNING, "No origtime?!\n");
04623       DISPOSE(vms->curdir, vms->curmsg);
04624       ast_config_destroy(msg_cfg);
04625       return 0;
04626    }
04627 
04628    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
04629    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
04630    category = ast_variable_retrieve(msg_cfg, "message", "category");
04631 
04632    context = ast_variable_retrieve(msg_cfg, "message", "context");
04633    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
04634       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
04635    if (!res)
04636       res = play_message_category(chan, category);
04637    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
04638       res = play_message_datetime(chan, vmu, origtime, filename);
04639    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
04640       res = play_message_callerid(chan, vms, cid, context, 0);
04641    if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
04642       res = play_message_duration(chan, vms, duration, vmu->saydurationm);
04643    /* Allow pressing '1' to skip envelope / callerid */
04644    if (res == '1')
04645       res = 0;
04646    ast_config_destroy(msg_cfg);
04647 
04648    if (!res) {
04649       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
04650       vms->heard[vms->curmsg] = 1;
04651       if ((res = wait_file(chan, vms, vms->fn)) < 0) {
04652          ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn);
04653          res = 0;
04654       }
04655    }
04656    DISPOSE(vms->curdir, vms->curmsg);
04657    return res;
04658 }

static int play_message_callerid ( struct ast_channel chan,
struct vm_state vms,
char *  cid,
const char *  context,
int  callback 
) [static]

Definition at line 4308 of file app_voicemail.c.

References ast_callerid_parse(), AST_DIGIT_ANY, ast_fileexists(), ast_log(), ast_say_digit_str(), ast_stream_and_wait(), ast_strlen_zero(), ast_verbose(), cidinternalcontexts, LOG_DEBUG, MAX_NUM_CID_CONTEXTS, name, option_debug, option_verbose, VERBOSE_PREFIX_3, VM_SPOOL_DIR, and wait_file2().

Referenced by advanced_options(), and play_message().

04309 {
04310    int res = 0;
04311    int i;
04312    char *callerid, *name;
04313    char prefile[PATH_MAX] = "";
04314    
04315 
04316    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
04317    /* BB: Still need to change this so that if this function is called by the message envelope (and someone is explicitly requesting to hear the CID), it does not check to see if CID is enabled in the config file */
04318    if ((cid == NULL)||(context == NULL))
04319       return res;
04320 
04321    /* Strip off caller ID number from name */
04322    if (option_debug > 2)
04323       ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
04324    ast_callerid_parse(cid, &name, &callerid);
04325    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
04326       /* Check for internal contexts and only */
04327       /* say extension when the call didn't come from an internal context in the list */
04328       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
04329          if (option_debug > 2)
04330             ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
04331          if ((strcmp(cidinternalcontexts[i], context) == 0))
04332             break;
04333       }
04334       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
04335          if (!res) {
04336             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
04337             if (!ast_strlen_zero(prefile)) {
04338             /* See if we can find a recorded name for this person instead of their extension number */
04339                if (ast_fileexists(prefile, NULL, NULL) > 0) {
04340                   if (option_verbose > 2)
04341                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
04342                   if (!callback)
04343                      res = wait_file2(chan, vms, "vm-from");
04344                   res = ast_stream_and_wait(chan, prefile, chan->language, "");
04345                } else {
04346                   if (option_verbose > 2)
04347                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
04348                   /* BB: Say "from extension" as one saying to sound smoother */
04349                   if (!callback)
04350                      res = wait_file2(chan, vms, "vm-from-extension");
04351                   res = ast_say_digit_str(chan, callerid, "", chan->language);
04352                }
04353             }
04354          }
04355       }
04356 
04357       else if (!res){
04358          if (option_debug > 2)
04359             ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
04360          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
04361          if (!callback)
04362             res = wait_file2(chan, vms, "vm-from-phonenumber");
04363          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
04364       }
04365    } else {
04366       /* Number unknown */
04367       if (option_debug)
04368          ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
04369       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
04370       res = wait_file2(chan, vms, "vm-unknown-caller");
04371    }
04372    return res;
04373 }

static int play_message_category ( struct ast_channel chan,
const char *  category 
) [static]

Definition at line 4223 of file app_voicemail.c.

References ast_log(), ast_play_and_wait(), ast_strlen_zero(), and LOG_WARNING.

Referenced by play_message().

04224 {
04225    int res = 0;
04226 
04227    if (!ast_strlen_zero(category))
04228       res = ast_play_and_wait(chan, category);
04229 
04230    if (res) {
04231       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
04232       res = 0;
04233    }
04234 
04235    return res;
04236 }

static int play_message_datetime ( struct ast_channel chan,
struct ast_vm_user vmu,
const char *  origtime,
const char *  filename 
) [static]

Definition at line 4238 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_get_time_t(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), ast_say_date_with_format, ast_strlen_zero(), LOG_WARNING, pbx_builtin_setvar_helper(), t, and ast_vm_user::zonetag.

Referenced by advanced_options(), and play_message().

04239 {
04240    int res = 0;
04241    struct vm_zone *the_zone = NULL;
04242    time_t t;
04243 
04244    if (ast_get_time_t(origtime, &t, 0, NULL)) {
04245       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
04246       return 0;
04247    }
04248 
04249    /* Does this user have a timezone specified? */
04250    if (!ast_strlen_zero(vmu->zonetag)) {
04251       /* Find the zone in the list */
04252       struct vm_zone *z;
04253       AST_LIST_LOCK(&zones);
04254       AST_LIST_TRAVERSE(&zones, z, list) {
04255          if (!strcmp(z->name, vmu->zonetag)) {
04256             the_zone = z;
04257             break;
04258          }
04259       }
04260       AST_LIST_UNLOCK(&zones);
04261    }
04262 
04263 /* No internal variable parsing for now, so we'll comment it out for the time being */
04264 #if 0
04265    /* Set the DIFF_* variables */
04266    ast_localtime(&t, &time_now, NULL);
04267    tv_now = ast_tvnow();
04268    tnow = tv_now.tv_sec;
04269    ast_localtime(&tnow, &time_then, NULL);
04270 
04271    /* Day difference */
04272    if (time_now.tm_year == time_then.tm_year)
04273       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
04274    else
04275       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
04276    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
04277 
04278    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
04279 #endif
04280    if (the_zone)
04281       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
04282    else if (!strcasecmp(chan->language,"pl"))       /* POLISH syntax */
04283       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
04284    else if (!strcasecmp(chan->language,"se"))       /* SWEDISH syntax */
04285       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
04286    else if (!strcasecmp(chan->language,"no"))       /* NORWEGIAN syntax */
04287       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
04288    else if (!strcasecmp(chan->language,"de"))       /* GERMAN syntax */
04289       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
04290    else if (!strcasecmp(chan->language,"nl"))      /* DUTCH syntax */
04291       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
04292    else if (!strcasecmp(chan->language,"it"))      /* ITALIAN syntax */
04293       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' 'digits/hours' k 'digits/e' M 'digits/minutes'", NULL);
04294    else if (!strcasecmp(chan->language,"gr"))
04295       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
04296    else if (!strcasecmp(chan->language,"pt_BR"))
04297       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'digits/pt-de' B 'digits/pt-de' Y 'digits/pt-as' HM ", NULL);      
04298    else
04299       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
04300 #if 0
04301    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
04302 #endif
04303    return res;
04304 }

static int play_message_duration ( struct ast_channel chan,
struct vm_state vms,
const char *  duration,
int  minduration 
) [static]

Definition at line 4375 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_log(), ast_play_and_wait(), ast_say_number(), LOG_DEBUG, option_debug, say_and_wait(), and wait_file2().

Referenced by play_message().

04376 {
04377    int res = 0;
04378    int durationm;
04379    int durations;
04380    /* Verify that we have a duration for the message */
04381    if (duration == NULL)
04382       return res;
04383 
04384    /* Convert from seconds to minutes */
04385    durations=atoi(duration);
04386    durationm=(durations / 60);
04387 
04388    if (option_debug > 2)
04389       ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
04390 
04391    if ((!res) && (durationm >= minduration)) {
04392       res = wait_file2(chan, vms, "vm-duration");
04393 
04394       /* POLISH syntax */
04395       if (!strcasecmp(chan->language, "pl")) {
04396          div_t num = div(durationm, 10);
04397 
04398          if (durationm == 1) {
04399             res = ast_play_and_wait(chan, "digits/1z");
04400             res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
04401          } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
04402             if (num.rem == 2) {
04403                if (!num.quot) {
04404                   res = ast_play_and_wait(chan, "digits/2-ie");
04405                } else {
04406                   res = say_and_wait(chan, durationm - 2 , chan->language);
04407                   res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
04408                }
04409             } else {
04410                res = say_and_wait(chan, durationm, chan->language);
04411             }
04412             res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
04413          } else {
04414             res = say_and_wait(chan, durationm, chan->language);
04415             res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
04416          }
04417       /* DEFAULT syntax */
04418       } else {
04419          res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
04420          res = wait_file2(chan, vms, "vm-minutes");
04421       }
04422    }
04423    return res;
04424 }

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,
const char *  unlockdir,
signed char  record_gain,
struct vm_state vms 
) [static]

Definition at line 8189 of file app_voicemail.c.

References ast_channel_setoption(), AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_test_flag, ast_verbose(), ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, INTRO, LOG_WARNING, ast_vm_user::mailbox, maxsilence, option_verbose, silencethreshold, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.

Referenced by leave_voicemail(), vm_newuser(), vm_options(), and vm_tempgreeting().

08192 {
08193    /* Record message & let caller review or re-record it, or set options if applicable */
08194    int res = 0;
08195    int cmd = 0;
08196    int max_attempts = 3;
08197    int attempts = 0;
08198    int recorded = 0;
08199    int message_exists = 0;
08200    signed char zero_gain = 0;
08201    char tempfile[PATH_MAX];
08202    char *acceptdtmf = "#";
08203    char *canceldtmf = "";
08204 
08205    /* Note that urgent and private are for flagging messages as such in the future */
08206 
08207    /* barf if no pointer passed to store duration in */
08208    if (duration == NULL) {
08209       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
08210       return -1;
08211    }
08212 
08213    if (!outsidecaller)
08214       snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
08215    else
08216       ast_copy_string(tempfile, recordfile, sizeof(tempfile));
08217 
08218    cmd = '3';  /* Want to start by recording */
08219 
08220    while ((cmd >= 0) && (cmd != 't')) {
08221       switch (cmd) {
08222       case '1':
08223          if (!message_exists) {
08224             /* In this case, 1 is to record a message */
08225             cmd = '3';
08226             break;
08227          } else {
08228             /* Otherwise 1 is to save the existing message */
08229             if (option_verbose > 2)
08230                ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
08231             if (!outsidecaller)
08232                ast_filerename(tempfile, recordfile, NULL);
08233             ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
08234             if (!outsidecaller) {
08235                STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
08236                DISPOSE(recordfile, -1);
08237             }
08238             cmd = 't';
08239             return res;
08240          }
08241       case '2':
08242          /* Review */
08243          if (option_verbose > 2)
08244             ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
08245          cmd = ast_stream_and_wait(chan, tempfile, chan->language, AST_DIGIT_ANY);
08246          break;
08247       case '3':
08248          message_exists = 0;
08249          /* Record */
08250          if (recorded == 1) {
08251             if (option_verbose > 2)
08252                ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
08253          } else { 
08254             if (option_verbose > 2)
08255                ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
08256          }
08257          if (recorded && outsidecaller) {
08258             cmd = ast_play_and_wait(chan, INTRO);
08259             cmd = ast_play_and_wait(chan, "beep");
08260          }
08261          recorded = 1;
08262          /* After an attempt has been made to record message, we have to take care of INTRO and beep for incoming messages, but not for greetings */
08263          if (record_gain)
08264             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
08265          if (ast_test_flag(vmu, VM_OPERATOR))
08266             canceldtmf = "0";
08267          cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
08268          if (record_gain)
08269             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
08270          if (cmd == -1) {
08271             /* User has hung up, no options to give */
08272             if (!outsidecaller) {
08273                /* user was recording a greeting and they hung up, so let's delete the recording. */
08274                ast_filedelete(tempfile, NULL);
08275             }
08276             return cmd;
08277          }
08278          if (cmd == '0') {
08279             break;
08280          } else if (cmd == '*') {
08281             break;
08282          } 
08283 #if 0       
08284          else if (vmu->review && (*duration < 5)) {
08285             /* Message is too short */
08286             if (option_verbose > 2)
08287                ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
08288             cmd = ast_play_and_wait(chan, "vm-tooshort");
08289             cmd = ast_filedelete(tempfile, NULL);
08290             break;
08291          }
08292          else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
08293             /* Message is all silence */
08294             if (option_verbose > 2)
08295                ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
08296             cmd = ast_filedelete(tempfile, NULL);
08297             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
08298             if (!cmd)
08299                cmd = ast_play_and_wait(chan, "vm-speakup");
08300             break;
08301          }
08302 #endif
08303          else {
08304             /* If all is well, a message exists */
08305             message_exists = 1;
08306             cmd = 0;
08307          }
08308          break;
08309       case '4':
08310       case '5':
08311       case '6':
08312       case '7':
08313       case '8':
08314       case '9':
08315       case '*':
08316       case '#':
08317          cmd = ast_play_and_wait(chan, "vm-sorry");
08318          break;
08319 #if 0 
08320 /*  XXX Commented out for the moment because of the dangers of deleting
08321     a message while recording (can put the message numbers out of sync) */
08322       case '*':
08323          /* Cancel recording, delete message, offer to take another message*/
08324          cmd = ast_play_and_wait(chan, "vm-deleted");
08325          cmd = ast_filedelete(tempfile, NULL);
08326          if (outsidecaller) {
08327             res = vm_exec(chan, NULL);
08328             return res;
08329          }
08330          else
08331             return 1;
08332 #endif
08333       case '0':
08334          if (!ast_test_flag(vmu, VM_OPERATOR)) {
08335             cmd = ast_play_and_wait(chan, "vm-sorry");
08336             break;
08337          }
08338          if (message_exists || recorded) {
08339             cmd = ast_play_and_wait(chan, "vm-saveoper");
08340             if (!cmd)
08341                cmd = ast_waitfordigit(chan, 3000);
08342             if (cmd == '1') {
08343                ast_play_and_wait(chan, "vm-msgsaved");
08344                cmd = '0';
08345             } else {
08346                ast_play_and_wait(chan, "vm-deleted");
08347                DELETE(recordfile, -1, recordfile);
08348                cmd = '0';
08349             }
08350          }
08351          return cmd;
08352       default:
08353          /* If the caller is an ouside caller, and the review option is enabled,
08354             allow them to review the message, but let the owner of the box review
08355             their OGM's */
08356          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
08357             return cmd;
08358          if (message_exists) {
08359             cmd = ast_play_and_wait(chan, "vm-review");
08360          }
08361          else {
08362             cmd = ast_play_and_wait(chan, "vm-torerecord");
08363             if (!cmd)
08364                cmd = ast_waitfordigit(chan, 600);
08365          }
08366          
08367          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
08368             cmd = ast_play_and_wait(chan, "vm-reachoper");
08369             if (!cmd)
08370                cmd = ast_waitfordigit(chan, 600);
08371          }
08372 #if 0
08373          if (!cmd)
08374             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
08375 #endif
08376          if (!cmd)
08377             cmd = ast_waitfordigit(chan, 6000);
08378          if (!cmd) {
08379             attempts++;
08380          }
08381          if (attempts > max_attempts) {
08382             cmd = 't';
08383          }
08384       }
08385    }
08386    if (outsidecaller)
08387       ast_play_and_wait(chan, "vm-goodbye");
08388    if (cmd == 't')
08389       cmd = 0;
08390    return cmd;
08391 }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

Definition at line 562 of file app_voicemail.c.

References ast_copy_flags, AST_FLAGS_ALL, ast_vm_user::callback, callcontext, dialcontext, ast_vm_user::dialout, ast_vm_user::exit, exitcontext, globalflags, ast_vm_user::maxmsg, ast_vm_user::saydurationm, saydurationminfo, and ast_vm_user::volgain.

Referenced by append_mailbox(), find_user_realtime(), and load_config().

00563 {
00564    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00565    if (saydurationminfo)
00566       vmu->saydurationm = saydurationminfo;
00567    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00568    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00569    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00570    if (maxmsg)
00571       vmu->maxmsg = maxmsg;
00572    vmu->volgain = volgain;
00573 }

static void prep_email_sub_vars ( struct ast_channel ast,
struct ast_vm_user vmu,
int  msgnum,
char *  context,
char *  mailbox,
char *  cidnum,
char *  cidname,
char *  dur,
char *  date,
char *  passdata,
size_t  passdatasize,
const char *  category 
) [static]

Definition at line 1698 of file app_voicemail.c.

References ast_callerid_merge(), ast_strdupa, ast_vm_user::fullname, and pbx_builtin_setvar_helper().

Referenced by make_email_file(), and sendpage().

01699 {
01700    char callerid[256];
01701    /* Prepare variables for substition in email body and subject */
01702    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
01703    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
01704    snprintf(passdata, passdatasize, "%d", msgnum);
01705    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
01706    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
01707    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
01708    pbx_builtin_setvar_helper(ast, "VM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller"));
01709    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (cidname ? cidname : "an unknown caller"));
01710    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
01711    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
01712    pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
01713 }

static char* quote ( const char *  from,
char *  to,
size_t  len 
) [static]

Definition at line 1715 of file app_voicemail.c.

01716 {
01717    char *ptr = to;
01718    *ptr++ = '"';
01719    for (; ptr < to + len - 1; from++) {
01720       if (*from == '"')
01721          *ptr++ = '\\';
01722       else if (*from == '\0')
01723          break;
01724       *ptr++ = *from;
01725    }
01726    if (ptr < to + len - 1)
01727       *ptr++ = '"';
01728    *ptr = '\0';
01729    return to;
01730 }

static int reload ( void   )  [static]

Definition at line 7838 of file app_voicemail.c.

References load_config().

07839 {
07840    return(load_config());
07841 }

static void rename_file ( char *  sfn,
char *  dfn 
) [static]

Definition at line 1468 of file app_voicemail.c.

References ast_filerename().

01469 {
01470    char stxt[PATH_MAX];
01471    char dtxt[PATH_MAX];
01472    ast_filerename(sfn,dfn,NULL);
01473    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
01474    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
01475    rename(stxt, dtxt);
01476 }

static int resequence_mailbox ( struct ast_vm_user vmu,
char *  dir 
) [static]

Definition at line 3191 of file app_voicemail.c.

References ast_unlock_path(), ast_vm_user::context, ERROR_LOCK_PATH, EXISTS, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, RENAME, and vm_lock_path().

Referenced by open_mailbox().

03192 {
03193    /* we know max messages, so stop process when number is hit */
03194 
03195    int x,dest;
03196    char sfn[PATH_MAX];
03197    char dfn[PATH_MAX];
03198 
03199    if (vm_lock_path(dir))
03200       return ERROR_LOCK_PATH;
03201 
03202    for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
03203       make_file(sfn, sizeof(sfn), dir, x);
03204       if (EXISTS(dir, x, sfn, NULL)) {
03205          
03206          if (x != dest) {
03207             make_file(dfn, sizeof(dfn), dir, dest);
03208             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
03209          }
03210          
03211          dest++;
03212       }
03213    }
03214    ast_unlock_path(dir);
03215 
03216    return 0;
03217 }

static int reset_user_pw ( const char *  context,
const char *  mailbox,
const char *  newpass 
) [static]

Definition at line 761 of file app_voicemail.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and users.

Referenced by vm_change_password().

00762 {
00763    /* This function could be made to generate one from a database, too */
00764    struct ast_vm_user *cur;
00765    int res = -1;
00766    AST_LIST_LOCK(&users);
00767    AST_LIST_TRAVERSE(&users, cur, list) {
00768       if ((!context || !strcasecmp(context, cur->context)) &&
00769          (!strcasecmp(mailbox, cur->mailbox)))
00770             break;
00771    }
00772    if (cur) {
00773       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00774       res = 0;
00775    }
00776    AST_LIST_UNLOCK(&users);
00777    return res;
00778 }

static void run_externnotify ( char *  context,
char *  extension 
) [static]

Definition at line 2730 of file app_voicemail.c.

References ast_app_has_voicemail(), ast_log(), ast_safe_system(), ast_smdi_mwi_message_destroy(), ast_smdi_mwi_message_wait(), ast_smdi_mwi_set(), ast_smdi_mwi_unset(), ast_strlen_zero(), ASTOBJ_UNREF, ast_smdi_mwi_message::cause, externnotify, ast_smdi_mwi_message::fwd_st, inboxcount(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, smdi_iface, and SMDI_MWI_WAIT_TIMEOUT.

Referenced by forward_message(), notify_new_message(), and vm_execmain().

02731 {
02732    char arguments[255];
02733    char ext_context[256] = "";
02734    int newvoicemails = 0, oldvoicemails = 0;
02735    struct ast_smdi_mwi_message *mwi_msg;
02736 
02737    if (!ast_strlen_zero(context))
02738       snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
02739    else
02740       ast_copy_string(ext_context, extension, sizeof(ext_context));
02741 
02742    if (!strcasecmp(externnotify, "smdi")) {
02743       if (ast_app_has_voicemail(ext_context, NULL)) 
02744          ast_smdi_mwi_set(smdi_iface, extension);
02745       else
02746          ast_smdi_mwi_unset(smdi_iface, extension);
02747 
02748       if ((mwi_msg = ast_smdi_mwi_message_wait(smdi_iface, SMDI_MWI_WAIT_TIMEOUT))) {
02749          ast_log(LOG_ERROR, "Error executing SMDI MWI change for %s on %s\n", extension, smdi_iface->name);
02750          if (!strncmp(mwi_msg->cause, "INV", 3))
02751             ast_log(LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
02752          else if (!strncmp(mwi_msg->cause, "BLK", 3))
02753             ast_log(LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
02754          ast_log(LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
02755          ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
02756       } else {
02757          if (option_debug)
02758             ast_log(LOG_DEBUG, "Successfully executed SMDI MWI change for %s on %s\n", extension, smdi_iface->name);
02759       }
02760    } else if (!ast_strlen_zero(externnotify)) {
02761       if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
02762          ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
02763       } else {
02764          snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
02765          if (option_debug)
02766             ast_log(LOG_DEBUG, "Executing %s\n", arguments);
02767          ast_safe_system(arguments);
02768       }
02769    }
02770 }

static int save_to_folder ( struct ast_vm_user vmu,
struct vm_state vms,
int  msg,
int  box 
) [static]

Definition at line 3227 of file app_voicemail.c.

References ast_log(), ast_unlock_path(), ast_vm_user::context, COPY, create_dirpath(), vm_state::curdir, ERROR_LOCK_PATH, EXISTS, LOG_DEBUG, make_file(), ast_vm_user::maxmsg, mbox(), option_debug, vm_state::username, username, and vm_lock_path().

Referenced by close_mailbox(), and vm_execmain().

03228 {
03229 #ifdef IMAP_STORAGE
03230    /* we must use mbox(x) folder names, and copy the message there */
03231    /* simple. huh? */
03232    long res;
03233    char sequence[10];
03234 
03235    /* if save to Old folder, just leave in INBOX */
03236    if (box == 1) return 10;
03237    /* get the real IMAP message number for this message */
03238    snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
03239    if (option_debug > 2)
03240       ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,(char *) mbox(box));
03241    res = mail_copy(vms->mailstream,sequence,(char *) mbox(box));
03242    if (res == 1) return 0;
03243    return 1;
03244 #else
03245    char *dir = vms->curdir;
03246    char *username = vms->username;
03247    char *context = vmu->context;
03248    char sfn[PATH_MAX];
03249    char dfn[PATH_MAX];
03250    char ddir[PATH_MAX];
03251    const char *dbox = mbox(box);
03252    int x;
03253    make_file(sfn, sizeof(sfn), dir, msg);
03254    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
03255 
03256    if (vm_lock_path(ddir))
03257       return ERROR_LOCK_PATH;
03258 
03259    for (x = 0; x < vmu->maxmsg; x++) {
03260       make_file(dfn, sizeof(dfn), ddir, x);
03261       if (!EXISTS(ddir, x, dfn, NULL))
03262          break;
03263    }
03264    if (x >= vmu->maxmsg) {
03265       ast_unlock_path(ddir);
03266       return -1;
03267    }
03268    if (strcmp(sfn, dfn)) {
03269       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
03270    }
03271    ast_unlock_path(ddir);
03272 #endif
03273    return 0;
03274 }

static int say_and_wait ( struct ast_channel chan,
int  num,
const char *  language 
) [static]

static int sendmail ( char *  srcemail,
struct ast_vm_user vmu,
int  msgnum,
char *  context,
char *  mailbox,
char *  cidnum,
char *  cidname,
char *  attach,
char *  format,
int  duration,
int  attach_user_voicemail,
struct ast_channel chan,
const char *  category 
) [static]

Definition at line 1936 of file app_voicemail.c.

References ast_log(), ast_safe_system(), ast_strlen_zero(), ast_test_flag, ast_vm_user::email, globalflags, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, ast_vm_user::mailcmd, make_email_file(), option_debug, VM_ATTACH, and vm_mkftemp().

Referenced by forward_message(), and notify_new_message().

01937 {
01938    FILE *p=NULL;
01939    char tmp[80] = "/tmp/astmail-XXXXXX";
01940    char tmp2[256];
01941 
01942    if (vmu && ast_strlen_zero(vmu->email)) {
01943       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
01944       return(0);
01945    }
01946    if (!strcmp(format, "wav49"))
01947       format = "WAV";
01948    if (option_debug > 2)
01949       ast_log(LOG_DEBUG, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH));
01950    /* Make a temporary file instead of piping directly to sendmail, in case the mail
01951       command hangs */
01952    if ((p = vm_mkftemp(tmp)) == NULL) {
01953       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
01954       return -1;
01955    } else {
01956       make_email_file(p, srcemail, vmu, msgnum, context, mailbox, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
01957       fclose(p);
01958       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
01959       ast_safe_system(tmp2);
01960       if (option_debug > 2)
01961          ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
01962    }
01963    return 0;
01964 }

static int sendpage ( char *  srcemail,
char *  pager,
int  msgnum,
char *  context,
char *  mailbox,
char *  cidnum,
char *  cidname,
int  duration,
struct ast_vm_user vmu,
const char *  category 
) [static]

Definition at line 1966 of file app_voicemail.c.

References ast_channel_alloc(), ast_channel_free(), ast_log(), ast_safe_system(), AST_STATE_DOWN, fromstring, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailcmd, option_debug, pagerbody, pagerfromstring, pagersubject, pbx_substitute_variables_helper(), prep_email_sub_vars(), vm_mkftemp(), and vmu_tm().

Referenced by notify_new_message().

01967 {
01968    char date[256];
01969    char host[MAXHOSTNAMELEN] = "";
01970    char who[256];
01971    char dur[PATH_MAX];
01972    char tmp[80] = "/tmp/astmail-XXXXXX";
01973    char tmp2[PATH_MAX];
01974    struct tm tm;
01975    FILE *p;
01976 
01977    if ((p = vm_mkftemp(tmp)) == NULL) {
01978       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
01979       return -1;
01980    } else {
01981       gethostname(host, sizeof(host)-1);
01982       if (strchr(srcemail, '@'))
01983          ast_copy_string(who, srcemail, sizeof(who));
01984       else {
01985          snprintf(who, sizeof(who), "%s@%s", srcemail, host);
01986       }
01987       snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
01988       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
01989       fprintf(p, "Date: %s\n", date);
01990 
01991       if (*pagerfromstring) {
01992          struct ast_channel *ast;
01993          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
01994             char *passdata;
01995             int vmlen = strlen(fromstring)*3 + 200;
01996             if ((passdata = alloca(vmlen))) {
01997                memset(passdata, 0, vmlen);
01998                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
01999                pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen);
02000                fprintf(p, "From: %s <%s>\n", passdata, who);
02001             } else 
02002                ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
02003             ast_channel_free(ast);
02004          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
02005       } else
02006          fprintf(p, "From: Asterisk PBX <%s>\n", who);
02007       fprintf(p, "To: %s\n", pager);
02008       if (pagersubject) {
02009          struct ast_channel *ast;
02010          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
02011             char *passdata;
02012             int vmlen = strlen(pagersubject) * 3 + 200;
02013             if ((passdata = alloca(vmlen))) {
02014                memset(passdata, 0, vmlen);
02015                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
02016                pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen);
02017                fprintf(p, "Subject: %s\n\n", passdata);
02018             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
02019             ast_channel_free(ast);
02020          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
02021       } else
02022          fprintf(p, "Subject: New VM\n\n");
02023       strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
02024       if (pagerbody) {
02025          struct ast_channel *ast;
02026          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
02027             char *passdata;
02028             int vmlen = strlen(pagerbody)*3 + 200;
02029             if ((passdata = alloca(vmlen))) {
02030                memset(passdata, 0, vmlen);
02031                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
02032                pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen);
02033                fprintf(p, "%s\n", passdata);
02034             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
02035          ast_channel_free(ast);
02036          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
02037       } else {
02038          fprintf(p, "New %s long msg in box %s\n"
02039                "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
02040       }
02041       fclose(p);
02042       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
02043       ast_safe_system(tmp2);
02044       if (option_debug > 2)
02045          ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd);
02046    }
02047    return 0;
02048 }

static int unload_module ( void   )  [static]

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  maxlogins,
int  silent 
) [static]

Definition at line 6272 of file app_voicemail.c.

References adsi_begin(), adsi_login(), adsi_password(), ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitstream(), ast_channel::cid, ast_callerid::cid_num, find_user(), LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, ast_vm_user::password, and VERBOSE_PREFIX_3.

Referenced by vm_execmain(), and vmauthenticate().

06275 {
06276    int useadsi=0, valid=0, logretries=0;
06277    char password[AST_MAX_EXTENSION]="", *passptr;
06278    struct ast_vm_user vmus, *vmu = NULL;
06279 
06280    /* If ADSI is supported, setup login screen */
06281    adsi_begin(chan, &useadsi);
06282    if (!skipuser && useadsi)
06283       adsi_login(chan);
06284    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
06285       ast_log(LOG_WARNING, "Couldn't stream login file\n");
06286       return -1;
06287    }
06288    
06289    /* Authenticate them and get their mailbox/password */
06290    
06291    while (!valid && (logretries < maxlogins)) {
06292       /* Prompt for, and read in the username */
06293       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
06294          ast_log(LOG_WARNING, "Couldn't read username\n");
06295          return -1;
06296       }
06297       if (ast_strlen_zero(mailbox)) {
06298          if (chan->cid.cid_num) {
06299             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
06300          } else {
06301             if (option_verbose > 2)
06302                ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");  
06303             return -1;
06304          }
06305       }
06306       if (useadsi)
06307          adsi_password(chan);
06308 
06309       if (!ast_strlen_zero(prefix)) {
06310          char fullusername[80] = "";
06311          ast_copy_string(fullusername, prefix, sizeof(fullusername));
06312          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
06313          ast_copy_string(mailbox, fullusername, mailbox_size);
06314       }
06315 
06316       if (option_debug)
06317          ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
06318       vmu = find_user(&vmus, context, mailbox);
06319       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
06320          /* saved password is blank, so don't bother asking */
06321          password[0] = '\0';
06322       } else {
06323          if (ast_streamfile(chan, "vm-password", chan->language)) {
06324             ast_log(LOG_WARNING, "Unable to stream password file\n");
06325             return -1;
06326          }
06327          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
06328             ast_log(LOG_WARNING, "Unable to read password\n");
06329             return -1;
06330          }
06331       }
06332 
06333       if (vmu) {
06334          passptr = vmu->password;
06335          if (passptr[0] == '-') passptr++;
06336       }
06337       if (vmu && !strcmp(passptr, password))
06338          valid++;
06339       else {
06340          if (option_verbose > 2)
06341             ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
06342          if (!ast_strlen_zero(prefix))
06343             mailbox[0] = '\0';
06344       }
06345       logretries++;
06346       if (!valid) {
06347          if (skipuser || logretries >= maxlogins) {
06348             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
06349                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
06350                return -1;
06351             }
06352          } else {
06353             if (useadsi)
06354                adsi_login(chan);
06355             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
06356                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
06357                return -1;
06358             }
06359          }
06360          if (ast_waitstream(chan, "")) /* Channel is hung up */
06361             return -1;
06362       }
06363    }
06364    if (!valid && (logretries >= maxlogins)) {
06365       ast_stopstream(chan);
06366       ast_play_and_wait(chan, "vm-goodbye");
06367       return -1;
06368    }
06369    if (vmu && !skipuser) {
06370       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
06371    }
06372    return 0;
06373 }

static int vm_box_exists ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 7086 of file app_voicemail.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_goto_if_exists(), ast_log(), ast_module_user_add, ast_module_user_remove, ast_opt_priority_jumping, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::context, ast_channel::exten, find_user(), LOG_ERROR, LOG_WARNING, pbx_builtin_setvar_helper(), and ast_channel::priority.

Referenced by load_module().

07087 {
07088    struct ast_module_user *u;
07089    struct ast_vm_user svm;
07090    char *context, *box;
07091    int priority_jump = 0;
07092    AST_DECLARE_APP_ARGS(args,
07093       AST_APP_ARG(mbox);
07094       AST_APP_ARG(options);
07095    );
07096 
07097    if (ast_strlen_zero(data)) {
07098       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
07099       return -1;
07100    }
07101 
07102    u = ast_module_user_add(chan);
07103 
07104    box = ast_strdupa(data);
07105 
07106    AST_STANDARD_APP_ARGS(args, box);
07107 
07108    if (args.options) {
07109       if (strchr(args.options, 'j'))
07110          priority_jump = 1;
07111    }
07112 
07113    if ((context = strchr(args.mbox, '@'))) {
07114       *context = '\0';
07115       context++;
07116    }
07117 
07118    if (find_user(&svm, context, args.mbox)) {
07119       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
07120       if (priority_jump || ast_opt_priority_jumping)
07121          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
07122             ast_log(LOG_WARNING, "VM box %s@%s exists, but extension %s, priority %d doesn't exist\n", box, context, chan->exten, chan->priority + 101);
07123    } else
07124       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
07125    ast_module_user_remove(u);
07126    return 0;
07127 }

static int vm_browse_messages ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 6257 of file app_voicemail.c.

References vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_it(), and vm_browse_messages_pt().

Referenced by vm_execmain().

06258 {
06259    if (!strcasecmp(chan->language, "es")) {  /* SPANISH */
06260       return vm_browse_messages_es(chan, vms, vmu);
06261    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN */
06262       return vm_browse_messages_it(chan, vms, vmu);
06263    } else if (!strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) {   /* PORTUGUESE */
06264       return vm_browse_messages_pt(chan, vms, vmu);
06265    } else if (!strcasecmp(chan->language, "gr")){
06266       return vm_browse_messages_gr(chan, vms, vmu);   /* GREEK */
06267    } else { /* Default to English syntax */
06268       return vm_browse_messages_en(chan, vms, vmu);
06269    }
06270 }

static int vm_browse_messages_en ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 6180 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().

Referenced by vm_browse_messages().

06181 {
06182    int cmd=0;
06183 
06184    if (vms->lastmsg > -1) {
06185       cmd = play_message(chan, vmu, vms);
06186    } else {
06187       cmd = ast_play_and_wait(chan, "vm-youhave");
06188       if (!cmd) 
06189          cmd = ast_play_and_wait(chan, "vm-no");
06190       if (!cmd) {
06191          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06192          cmd = ast_play_and_wait(chan, vms->fn);
06193       }
06194       if (!cmd)
06195          cmd = ast_play_and_wait(chan, "vm-messages");
06196    }
06197    return cmd;
06198 }

static int vm_browse_messages_es ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 6220 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().

Referenced by vm_browse_messages().

06221 {
06222    int cmd=0;
06223 
06224    if (vms->lastmsg > -1) {
06225       cmd = play_message(chan, vmu, vms);
06226    } else {
06227       cmd = ast_play_and_wait(chan, "vm-youhaveno");
06228       if (!cmd)
06229          cmd = ast_play_and_wait(chan, "vm-messages");
06230       if (!cmd) {
06231          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06232          cmd = ast_play_and_wait(chan, vms->fn);
06233       }
06234    }
06235    return cmd;
06236 }

static int vm_browse_messages_gr ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 6152 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, play_message(), and vm_state::vmbox.

Referenced by vm_browse_messages().

06153 {
06154    int cmd=0;
06155 
06156    if (vms->lastmsg > -1) {
06157       cmd = play_message(chan, vmu, vms);
06158    } else {
06159       cmd = ast_play_and_wait(chan, "vm-youhaveno");
06160       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
06161          if (!cmd) {
06162             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
06163             cmd = ast_play_and_wait(chan, vms->fn);
06164          }
06165          if (!cmd)
06166             cmd = ast_play_and_wait(chan, "vm-messages");
06167       } else {
06168          if (!cmd)
06169             cmd = ast_play_and_wait(chan, "vm-messages");
06170          if (!cmd) {
06171             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06172             cmd = ast_play_and_wait(chan, vms->fn);
06173          }
06174       }
06175    } 
06176    return cmd;
06177 }

static int vm_browse_messages_it ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 6201 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().

Referenced by vm_browse_messages().

06202 {
06203    int cmd=0;
06204 
06205    if (vms->lastmsg > -1) {
06206       cmd = play_message(chan, vmu, vms);
06207    } else {
06208       cmd = ast_play_and_wait(chan, "vm-no");
06209       if (!cmd)
06210          cmd = ast_play_and_wait(chan, "vm-message");
06211       if (!cmd) {
06212          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06213          cmd = ast_play_and_wait(chan, vms->fn);
06214       }
06215    }
06216    return cmd;
06217 }

static int vm_browse_messages_pt ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 6239 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().

Referenced by vm_browse_messages().

06240 {
06241    int cmd=0;
06242 
06243    if (vms->lastmsg > -1) {
06244       cmd = play_message(chan, vmu, vms);
06245    } else {
06246       cmd = ast_play_and_wait(chan, "vm-no");
06247       if (!cmd) {
06248          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06249          cmd = ast_play_and_wait(chan, vms->fn);
06250       }
06251       if (!cmd)
06252          cmd = ast_play_and_wait(chan, "vm-messages");
06253    }
06254    return cmd;
06255 }

static void vm_change_password ( struct ast_vm_user vmu,
const char *  newpassword 
) [static]

Definition at line 780 of file app_voicemail.c.

References ast_category_browse(), ast_category_get(), ast_config_load_with_comments(), ast_log(), ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), change_password_realtime(), config_text_file_save(), ast_vm_user::context, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, option_debug, ast_vm_user::password, reset_user_pw(), var, and VOICEMAIL_CONFIG.

Referenced by vm_newuser(), and vm_options().

00781 {
00782    struct ast_config   *cfg=NULL;
00783    struct ast_variable *var=NULL;
00784    struct ast_category *cat=NULL;
00785    char *category=NULL, *value=NULL, *new=NULL;
00786    const char *tmp=NULL;
00787                
00788    if (!change_password_realtime(vmu, newpassword))
00789       return;
00790 
00791    /* check voicemail.conf */
00792    if ((cfg = ast_config_load_with_comments(VOICEMAIL_CONFIG))) {
00793       while ((category = ast_category_browse(cfg, category))) {
00794          if (!strcasecmp(category, vmu->context)) {
00795             tmp = ast_variable_retrieve(cfg, category, vmu->mailbox);
00796             if (!tmp) {
00797                ast_log(LOG_WARNING, "We could not find the mailbox.\n");
00798                break;
00799             }
00800             value = strstr(tmp,",");
00801             if (!value) {
00802                ast_log(LOG_WARNING, "variable has bad format.\n");
00803                break;
00804             }
00805             new = alloca((strlen(value)+strlen(newpassword)+1));
00806             sprintf(new,"%s%s", newpassword, value);
00807             if (!(cat = ast_category_get(cfg, category))) {
00808                ast_log(LOG_WARNING, "Failed to get category structure.\n");
00809                break;
00810             }
00811             ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
00812          }
00813       }
00814       /* save the results */
00815       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00816       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00817       config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
00818    }
00819    category = NULL;
00820    var = NULL;
00821    /* check users.conf and update the password stored for the mailbox*/
00822    /* if no vmsecret entry exists create one. */
00823    if ((cfg = ast_config_load_with_comments("users.conf"))) {
00824       if (option_debug > 3)
00825          ast_log(LOG_DEBUG, "we are looking for %s\n", vmu->mailbox);
00826       while ((category = ast_category_browse(cfg, category))) {
00827          if (option_debug > 3)
00828             ast_log(LOG_DEBUG, "users.conf: %s\n", category);
00829          if (!strcasecmp(category, vmu->mailbox)) {
00830             if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) {
00831                if (option_debug > 3)
00832                   ast_log(LOG_DEBUG, "looks like we need to make vmsecret!\n");
00833                var = ast_variable_new("vmsecret", newpassword);
00834             } 
00835             new = alloca(strlen(newpassword)+1);
00836             sprintf(new, "%s", newpassword);
00837             if (!(cat = ast_category_get(cfg, category))) {
00838                if (option_debug > 3)
00839                   ast_log(LOG_DEBUG, "failed to get category!\n");
00840                break;
00841             }
00842             if (!var)      
00843                ast_variable_update(cat, "vmsecret", new, NULL, 0);
00844             else
00845                ast_variable_append(cat, var);
00846          }
00847       }
00848       /* save the results and clean things up */
00849       reset_user_pw(vmu->context, vmu->mailbox, newpassword);  
00850       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00851       config_text_file_save("users.conf", cfg, "AppVoicemail");
00852    }
00853 }

static void vm_change_password_shell ( struct ast_vm_user vmu,
char *  newpassword 
) [static]

Definition at line 855 of file app_voicemail.c.

References ast_safe_system(), ast_vm_user::context, ext_pass_cmd, ast_vm_user::mailbox, and ast_vm_user::password.

Referenced by vm_newuser(), and vm_options().

00856 {
00857    char buf[255];
00858    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00859    if (!ast_safe_system(buf))
00860       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00861 }

static int vm_delete ( char *  file  )  [static]

Definition at line 1562 of file app_voicemail.c.

References ast_filedelete().

01563 {
01564    char *txt;
01565    int txtsize = 0;
01566 
01567    txtsize = (strlen(file) + 5)*sizeof(char);
01568    txt = alloca(txtsize);
01569    /* Sprintf here would safe because we alloca'd exactly the right length,
01570     * but trying to eliminate all sprintf's anyhow
01571     */
01572    snprintf(txt, txtsize, "%s.txt", file);
01573    unlink(txt);
01574    return ast_filedelete(file, NULL);
01575 }

static int vm_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 6939 of file app_voicemail.c.

References ast_channel::_state, ast_answer(), AST_APP_ARG, ast_app_getdata(), ast_app_parse_options(), ast_copy_flags, AST_DECLARE_APP_ARGS, ast_goto_if_exists(), ast_log(), ast_module_user_add, ast_module_user_remove, ast_opt_priority_jumping, ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_channel::context, ERROR_LOCK_PATH, ast_channel::exten, leave_voicemail(), LOG_ERROR, LOG_WARNING, OPT_ARG_ARRAY_SIZE, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_PRIORITY_JUMP, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), ast_channel::priority, and leave_vm_options::record_gain.

Referenced by load_module(), and play_record_review().

06940 {
06941    int res = 0;
06942    struct ast_module_user *u;
06943    char *tmp;
06944    struct leave_vm_options leave_options;
06945    struct ast_flags flags = { 0 };
06946    static int deprecate_warning = 0;
06947    char *opts[OPT_ARG_ARRAY_SIZE];
06948    AST_DECLARE_APP_ARGS(args,
06949       AST_APP_ARG(argv0);
06950       AST_APP_ARG(argv1);
06951    );
06952 
06953    u = ast_module_user_add(chan);
06954    
06955    memset(&leave_options, 0, sizeof(leave_options));
06956 
06957    if (chan->_state != AST_STATE_UP)
06958       ast_answer(chan);
06959 
06960    if (!ast_strlen_zero(data)) {
06961       tmp = ast_strdupa(data);
06962       AST_STANDARD_APP_ARGS(args, tmp);
06963       if (args.argc == 2) {
06964          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
06965             ast_module_user_remove(u);
06966             return -1;
06967          }
06968          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
06969          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
06970             int gain;
06971 
06972             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
06973                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
06974                ast_module_user_remove(u);
06975                return -1;
06976             } else {
06977                leave_options.record_gain = (signed char) gain;
06978             }
06979          }
06980       } else {
06981          /* old style options parsing */
06982          int old = 0;
06983          char *orig_argv0 = args.argv0;
06984          while (*(args.argv0)) {
06985             if (*(args.argv0) == 's') {
06986                old = 1;
06987                ast_set_flag(&leave_options, OPT_SILENT);
06988             } else if (*(args.argv0) == 'b') {
06989                old = 1;
06990                ast_set_flag(&leave_options, OPT_BUSY_GREETING);
06991             } else if (*(args.argv0) == 'u') {
06992                old = 1;
06993                ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
06994             } else if (*(args.argv0) == 'j') {
06995                old = 1;
06996                ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
06997             } else
06998                break;
06999             (args.argv0)++;
07000          }
07001          if (!deprecate_warning && old) {
07002             deprecate_warning = 1;
07003             ast_log(LOG_WARNING, "Prefixing the mailbox with an option is deprecated ('%s').\n", orig_argv0);
07004             ast_log(LOG_WARNING, "Please move all leading options to the second argument.\n");
07005          }
07006       }
07007    } else {
07008       char tmp[256];
07009       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
07010       if (res < 0) {
07011          ast_module_user_remove(u);
07012          return res;
07013       }
07014       if (ast_strlen_zero(tmp)) {
07015          ast_module_user_remove(u);
07016          return 0;
07017       }
07018       args.argv0 = ast_strdupa(tmp);
07019    }
07020 
07021    res = leave_voicemail(chan, args.argv0, &leave_options);
07022 
07023    if (res == ERROR_LOCK_PATH) {
07024       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
07025       /*Send the call to n+101 priority, where n is the current priority*/
07026       if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
07027          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
07028             ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
07029       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
07030       res = 0;
07031    }
07032    
07033    ast_module_user_remove(u);
07034 
07035    return res;
07036 }

static int vm_execmain ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 6375 of file app_voicemail.c.

References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), advanced_options(), ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_parse_options(), ast_calloc, AST_DECLARE_APP_ARGS, ast_log(), ast_module_user_add, ast_module_user_remove, ast_play_and_wait(), ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_waitfordigit(), ast_vm_user::callback, close_mailbox(), ast_vm_user::context, create_dirpath(), vm_state::curdir, vm_state::curmsg, vm_state::deleted, ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), vm_state::fn, forward_message(), free, free_user(), get_folder2(), globalflags, has_voicemail(), vm_state::heard, ast_vm_user::language, vm_state::lastmsg, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, make_file(), manager_event(), maxlogins, ast_vm_user::maxmsg, vm_state::newmessages, vm_state::oldmessages, open_mailbox(), OPT_ARG_ARRAY_SIZE, OPT_ARG_PLAYFOLDER, OPT_ARG_RECORDGAIN, OPT_AUTOPLAY, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, option_debug, option_verbose, parse(), ast_vm_user::password, play_message(), vm_state::repeats, run_externnotify(), save_to_folder(), say_and_wait(), vm_state::starting, vm_state::username, VERBOSE_PREFIX_3, vm_authenticate(), vm_browse_messages(), VM_FORCEGREET, VM_FORCENAME, vm_instructions(), vm_intro(), vm_newuser(), vm_options(), vm_play_folder_name(), VM_SKIPAFTERCMD, VM_SVMAIL, vm_state::vmbox, and vmfmts.

Referenced by load_module().

06376 {
06377    /* XXX This is, admittedly, some pretty horrendus code.  For some
06378       reason it just seemed a lot easier to do with GOTO's.  I feel
06379       like I'm back in my GWBASIC days. XXX */
06380    int res=-1;
06381    int cmd=0;
06382    int valid = 0;
06383    struct ast_module_user *u;
06384    char prefixstr[80] ="";
06385    char ext_context[256]="";
06386    int box;
06387    int useadsi = 0;
06388    int skipuser = 0;
06389    struct vm_state vms;
06390    struct ast_vm_user *vmu = NULL, vmus;
06391    char *context=NULL;
06392    int silentexit = 0;
06393    struct ast_flags flags = { 0 };
06394    signed char record_gain = 0;
06395    int play_auto = 0;
06396    int play_folder = 0;
06397 #ifdef IMAP_STORAGE
06398    int deleted = 0;
06399 #endif
06400    u = ast_module_user_add(chan);
06401 
06402    /* Add the vm_state to the active list and keep it active */
06403    memset(&vms, 0, sizeof(vms));
06404    vms.lastmsg = -1;
06405 
06406    memset(&vmus, 0, sizeof(vmus));
06407 
06408    if (chan->_state != AST_STATE_UP) {
06409       if (option_debug)
06410          ast_log(LOG_DEBUG, "Before ast_answer\n");
06411       ast_answer(chan);
06412    }
06413 
06414    if (!ast_strlen_zero(data)) {
06415       char *opts[OPT_ARG_ARRAY_SIZE];
06416       char *parse;
06417       AST_DECLARE_APP_ARGS(args,
06418          AST_APP_ARG(argv0);
06419          AST_APP_ARG(argv1);
06420       );
06421 
06422       parse = ast_strdupa(data);
06423 
06424       AST_STANDARD_APP_ARGS(args, parse);
06425 
06426       if (args.argc == 2) {
06427          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
06428             ast_module_user_remove(u);
06429             return -1;
06430          }
06431          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
06432             int gain;
06433             if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
06434                if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
06435                   ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
06436                   ast_module_user_remove(u);
06437                   return -1;
06438                } else {
06439                   record_gain = (signed char) gain;
06440                }
06441             } else {
06442                ast_log(LOG_WARNING, "Invalid Gain level set with option g\n");
06443             }
06444          }
06445          if (ast_test_flag(&flags, OPT_AUTOPLAY) ) {
06446             play_auto = 1;
06447             if (opts[OPT_ARG_PLAYFOLDER]) {
06448                if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%d", &play_folder) != 1) {
06449                   ast_log(LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]);
06450                }
06451             } else {
06452                ast_log(LOG_WARNING, "Invalid folder set with option a\n");
06453             }  
06454             if ( play_folder > 9 || play_folder < 0) {
06455                ast_log(LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder);
06456                play_folder = 0;
06457             }
06458          }
06459       } else {
06460          /* old style options parsing */
06461          while (*(args.argv0)) {
06462             if (*(args.argv0) == 's')
06463                ast_set_flag(&flags, OPT_SILENT);
06464             else if (*(args.argv0) == 'p')
06465                ast_set_flag(&flags, OPT_PREPEND_MAILBOX);
06466             else 
06467                break;
06468             (args.argv0)++;
06469          }
06470 
06471       }
06472 
06473       valid = ast_test_flag(&flags, OPT_SILENT);
06474 
06475       if ((context = strchr(args.argv0, '@')))
06476          *context++ = '\0';
06477 
06478       if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
06479          ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr));
06480       else
06481          ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
06482 
06483       if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
06484          skipuser++;
06485       else
06486          valid = 0;
06487    }
06488 
06489    if (!valid)
06490       res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
06491 
06492    if (option_debug)
06493       ast_log(LOG_DEBUG, "After vm_authenticate\n");
06494    if (!res) {
06495       valid = 1;
06496       if (!skipuser)
06497          vmu = &vmus;
06498    } else {
06499       res = 0;
06500    }
06501 
06502    /* If ADSI is supported, setup login screen */
06503    adsi_begin(chan, &useadsi);
06504 
06505 #ifdef IMAP_STORAGE
06506    vms.interactive = 1;
06507    vms.updated = 1;
06508    vmstate_insert(&vms);
06509    init_vm_state(&vms);
06510 #endif
06511    if (!valid)
06512       goto out;
06513 
06514    if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) {
06515       /* TODO: Handle memory allocation failure */
06516    }
06517    if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) {
06518       /* TODO: Handle memory allocation failure */
06519    }
06520    
06521    /* Set language from config to override channel language */
06522    if (!ast_strlen_zero(vmu->language))
06523       ast_string_field_set(chan, language, vmu->language);
06524    create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
06525    /* Retrieve old and new message counts */
06526    if (option_debug)
06527       ast_log(LOG_DEBUG, "Before open_mailbox\n");
06528    res = open_mailbox(&vms, vmu, 1);
06529    if (res == ERROR_LOCK_PATH)
06530       goto out;
06531    vms.oldmessages = vms.lastmsg + 1;
06532    if (option_debug > 2)
06533       ast_log(LOG_DEBUG, "Number of old messages: %d\n",vms.oldmessages);
06534    /* Start in INBOX */
06535    res = open_mailbox(&vms, vmu, 0);
06536    if (res == ERROR_LOCK_PATH)
06537       goto out;
06538    vms.newmessages = vms.lastmsg + 1;
06539    if (option_debug > 2)
06540       ast_log(LOG_DEBUG, "Number of new messages: %d\n",vms.newmessages);
06541       
06542    /* Select proper mailbox FIRST!! */
06543    if (play_auto) {
06544       res = open_mailbox(&vms, vmu, play_folder);
06545       if (res == ERROR_LOCK_PATH)
06546          goto out;
06547 
06548       /* If there are no new messages, inform the user and hangup */
06549       if (vms.lastmsg == -1) {
06550          cmd = vm_browse_messages(chan, &vms, vmu);
06551          res = 0;
06552          goto out;
06553       }
06554    } else {
06555       if (!vms.newmessages && vms.oldmessages) {
06556          /* If we only have old messages start here */
06557          res = open_mailbox(&vms, vmu, 1);
06558          play_folder = 1;
06559          if (res == ERROR_LOCK_PATH)
06560             goto out;
06561       }
06562    }
06563 
06564    if (useadsi)
06565       adsi_status(chan, &vms);
06566    res = 0;
06567 
06568    /* Check to see if this is a new user */
06569    if (!strcasecmp(vmu->mailbox, vmu->password) && 
06570       (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) {
06571       if (ast_play_and_wait(chan, "vm-newuser") == -1)
06572          ast_log(LOG_WARNING, "Couldn't stream new user file\n");
06573       cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
06574       if ((cmd == 't') || (cmd == '#')) {
06575          /* Timeout */
06576          res = 0;
06577          goto out;
06578       } else if (cmd < 0) {
06579          /* Hangup */
06580          res = -1;
06581          goto out;
06582       }
06583    }
06584 #ifdef IMAP_STORAGE
06585       if (option_debug > 2)
06586          ast_log(LOG_DEBUG, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit);
06587       if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
06588          if (option_debug)
06589             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!!\n");
06590          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
06591       }
06592       if (option_debug > 2)
06593          ast_log(LOG_DEBUG, "Checking quotas: User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
06594       if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) {
06595          ast_log(LOG_WARNING, "No more messages possible.  User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
06596          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
06597       }
06598 #endif
06599    if (play_auto) {
06600       cmd = '1';
06601    } else {
06602       cmd = vm_intro(chan, vmu, &vms);
06603    }
06604 
06605    vms.repeats = 0;
06606    vms.starting = 1;
06607    while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
06608       /* Run main menu */
06609       switch (cmd) {
06610       case '1':
06611          vms.curmsg = 0;
06612          /* Fall through */
06613       case '5':
06614          cmd = vm_browse_messages(chan, &vms, vmu);
06615          break;
06616       case '2': /* Change folders */
06617          if (useadsi)
06618             adsi_folders(chan, 0, "Change to folder...");
06619          cmd = get_folder2(chan, "vm-changeto", 0);
06620          if (cmd == '#') {
06621             cmd = 0;
06622          } else if (cmd > 0) {
06623             cmd = cmd - '0';
06624             res = close_mailbox(&vms, vmu);
06625             if (res == ERROR_LOCK_PATH)
06626                goto out;
06627             res = open_mailbox(&vms, vmu, cmd);
06628             if (res == ERROR_LOCK_PATH)
06629                goto out;
06630             play_folder = cmd;
06631             cmd = 0;
06632          }
06633          if (useadsi)
06634             adsi_status2(chan, &vms);
06635             
06636          if (!cmd)
06637             cmd = vm_play_folder_name(chan, vms.vmbox);
06638 
06639          vms.starting = 1;
06640          break;
06641       case '3': /* Advanced options */
06642          cmd = 0;
06643          vms.repeats = 0;
06644          while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
06645             switch (cmd) {
06646             case '1': /* Reply */
06647                if (vms.lastmsg > -1 && !vms.starting) {
06648                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
06649                   if (cmd == ERROR_LOCK_PATH) {
06650                      res = cmd;
06651                      goto out;
06652                   }
06653                } else
06654                   cmd = ast_play_and_wait(chan, "vm-sorry");
06655                cmd = 't';
06656                break;
06657             case '2': /* Callback */
06658                if (option_verbose > 2 && !vms.starting)
06659                   ast_verbose( VERBOSE_PREFIX_3 "Callback Requested\n");
06660                if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
06661                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
06662                   if (cmd == 9) {
06663                      silentexit = 1;
06664                      goto out;
06665                   } else if (cmd == ERROR_LOCK_PATH) {
06666                      res = cmd;
06667                      goto out;
06668                   }
06669                }
06670                else 
06671                   cmd = ast_play_and_wait(chan, "vm-sorry");
06672                cmd = 't';
06673                break;
06674             case '3': /* Envelope */
06675                if (vms.lastmsg > -1 && !vms.starting) {
06676                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
06677                   if (cmd == ERROR_LOCK_PATH) {
06678                      res = cmd;
06679                      goto out;
06680                   }
06681                } else
06682                   cmd = ast_play_and_wait(chan, "vm-sorry");
06683                cmd = 't';
06684                break;
06685             case '4': /* Dialout */
06686                if (!ast_strlen_zero(vmu->dialout)) {
06687                   cmd = dialout(chan, vmu, NULL, vmu->dialout);
06688                   if (cmd == 9) {
06689                      silentexit = 1;
06690                      goto out;
06691                   }
06692                }
06693                else 
06694                   cmd = ast_play_and_wait(chan, "vm-sorry");
06695                cmd = 't';
06696                break;
06697 
06698             case '5': /* Leave VoiceMail */
06699                if (ast_test_flag(vmu, VM_SVMAIL)) {
06700                   cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
06701                   if (cmd == ERROR_LOCK_PATH) {
06702                      res = cmd;
06703                      ast_log(LOG_WARNING, "forward_message failed to lock path.\n");
06704                      goto out;
06705                   }
06706                } else
06707                   cmd = ast_play_and_wait(chan,"vm-sorry");
06708                cmd='t';
06709                break;
06710                
06711             case '*': /* Return to main menu */
06712                cmd = 't';
06713                break;
06714 
06715             default:
06716                cmd = 0;
06717                if (!vms.starting) {
06718                   cmd = ast_play_and_wait(chan, "vm-toreply");
06719                }
06720                if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
06721                   cmd = ast_play_and_wait(chan, "vm-tocallback");
06722                }
06723                if (!cmd && !vms.starting) {
06724                   cmd = ast_play_and_wait(chan, "vm-tohearenv");
06725                }
06726                if (!ast_strlen_zero(vmu->dialout) && !cmd) {
06727                   cmd = ast_play_and_wait(chan, "vm-tomakecall");
06728                }
06729                if (ast_test_flag(vmu, VM_SVMAIL) && !cmd)
06730                   cmd=ast_play_and_wait(chan, "vm-leavemsg");
06731                if (!cmd)
06732                   cmd = ast_play_and_wait(chan, "vm-starmain");
06733                if (!cmd)
06734                   cmd = ast_waitfordigit(chan,6000);
06735                if (!cmd)
06736                   vms.repeats++;
06737                if (vms.repeats > 3)
06738                   cmd = 't';
06739             }
06740          }
06741          if (cmd == 't') {
06742             cmd = 0;
06743             vms.repeats = 0;
06744          }
06745          break;
06746       case '4':
06747          if (vms.curmsg > 0) {
06748             vms.curmsg--;
06749             cmd = play_message(chan, vmu, &vms);
06750          } else {
06751             cmd = ast_play_and_wait(chan, "vm-nomore");
06752          }
06753          break;
06754       case '6':
06755          if (vms.curmsg < vms.lastmsg) {
06756             vms.curmsg++;
06757             cmd = play_message(chan, vmu, &vms);
06758          } else {
06759             cmd = ast_play_and_wait(chan, "vm-nomore");
06760          }
06761          break;
06762       case '7':
06763          if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
06764             vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
06765             if (useadsi)
06766                adsi_delete(chan, &vms);
06767             if (vms.deleted[vms.curmsg]) {
06768                if (play_folder == 0)
06769                   vms.newmessages--;
06770                else if (play_folder == 1)
06771                   vms.oldmessages--;
06772                cmd = ast_play_and_wait(chan, "vm-deleted");
06773             }
06774             else {
06775                if (play_folder == 0)
06776                   vms.newmessages++;
06777                else if (play_folder == 1)
06778                   vms.oldmessages++;
06779                cmd = ast_play_and_wait(chan, "vm-undeleted");
06780             }
06781             if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
06782                if (vms.curmsg < vms.lastmsg) {
06783                   vms.curmsg++;
06784                   cmd = play_message(chan, vmu, &vms);
06785                } else {
06786                   cmd = ast_play_and_wait(chan, "vm-nomore");
06787                }
06788             }
06789          } else /* Delete not valid if we haven't selected a message */
06790             cmd = 0;
06791 #ifdef IMAP_STORAGE
06792          deleted = 1;
06793 #endif
06794          break;
06795    
06796       case '8':
06797          if (vms.lastmsg > -1) {
06798             cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain);
06799             if (cmd == ERROR_LOCK_PATH) {
06800                res = cmd;
06801                goto out;
06802             }
06803          } else
06804             cmd = ast_play_and_wait(chan, "vm-nomore");
06805          break;
06806       case '9':
06807          if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) {
06808             /* No message selected */
06809             cmd = 0;
06810             break;
06811          }
06812          if (useadsi)
06813             adsi_folders(chan, 1, "Save to folder...");
06814          cmd = get_folder2(chan, "vm-savefolder", 1);
06815          box = 0; /* Shut up compiler */
06816          if (cmd == '#') {
06817             cmd = 0;
06818             break;
06819          } else if (cmd > 0) {
06820             box = cmd = cmd - '0';
06821             cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd);
06822             if (cmd == ERROR_LOCK_PATH) {
06823                res = cmd;
06824                goto out;
06825 #ifdef IMAP_STORAGE
06826             } else if (cmd == 10) {
06827                goto out;
06828 #endif
06829             } else if (!cmd) {
06830                vms.deleted[vms.curmsg] = 1;
06831             } else {
06832                vms.deleted[vms.curmsg] = 0;
06833                vms.heard[vms.curmsg] = 0;
06834             }
06835          }
06836          make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
06837          if (useadsi)
06838             adsi_message(chan, &vms);
06839          snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
06840          if (!cmd) {
06841             cmd = ast_play_and_wait(chan, "vm-message");
06842             if (!cmd)
06843                cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
06844             if (!cmd)
06845                cmd = ast_play_and_wait(chan, "vm-savedto");
06846             if (!cmd)
06847                cmd = vm_play_folder_name(chan, vms.fn);
06848          } else {
06849             cmd = ast_play_and_wait(chan, "vm-mailboxfull");
06850          }
06851          if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
06852             if (vms.curmsg < vms.lastmsg) {
06853                vms.curmsg++;
06854                cmd = play_message(chan, vmu, &vms);
06855             } else {
06856                cmd = ast_play_and_wait(chan, "vm-nomore");
06857             }
06858          }
06859          break;
06860       case '*':
06861          if (!vms.starting) {
06862             cmd = ast_play_and_wait(chan, "vm-onefor");
06863             if (!cmd)
06864                cmd = vm_play_folder_name(chan, vms.vmbox);
06865             if (!cmd)
06866                cmd = ast_play_and_wait(chan, "vm-opts");
06867             if (!cmd)
06868                cmd = vm_instructions(chan, &vms, 1);
06869          } else
06870             cmd = 0;
06871          break;
06872       case '0':
06873          cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
06874          if (useadsi)
06875             adsi_status(chan, &vms);
06876          break;
06877       default: /* Nothing */
06878          cmd = vm_instructions(chan, &vms, 0);
06879          break;
06880       }
06881    }
06882    if ((cmd == 't') || (cmd == '#')) {
06883       /* Timeout */
06884       res = 0;
06885    } else {
06886       /* Hangup */
06887       res = -1;
06888    }
06889 
06890 out:
06891    if (res > -1) {
06892       ast_stopstream(chan);
06893       adsi_goodbye(chan);
06894       if (valid) {
06895          if (silentexit)
06896             res = ast_play_and_wait(chan, "vm-dialout");
06897          else 
06898             res = ast_play_and_wait(chan, "vm-goodbye");
06899          if (res > 0)
06900             res = 0;
06901       }
06902       if (useadsi)
06903          ast_adsi_unload_session(chan);
06904    }
06905    if (vmu)
06906       close_mailbox(&vms, vmu);
06907    if (valid) {
06908       snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
06909       manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
06910       run_externnotify(vmu->context, vmu->mailbox);
06911    }
06912 #ifdef IMAP_STORAGE
06913    /* expunge message - use UID Expunge if supported on IMAP server*/
06914    if (option_debug > 2)
06915       ast_log(LOG_DEBUG, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup);
06916    if (vmu && deleted == 1 && expungeonhangup == 1) {
06917 #ifdef HAVE_IMAP_TK2006
06918       if (LEVELUIDPLUS (vms.mailstream)) {
06919          mail_expunge_full(vms.mailstream,NIL,EX_UID);
06920       } else 
06921 #endif
06922          mail_expunge(vms.mailstream);
06923    }
06924    /*  before we delete the state, we should copy pertinent info
06925     *  back to the persistent model */
06926    vmstate_delete(&vms);
06927 #endif
06928    if (vmu)
06929       free_user(vmu);
06930    if (vms.deleted)
06931       free(vms.deleted);
06932    if (vms.heard)
06933       free(vms.heard);
06934    ast_module_user_remove(u);
06935 
06936    return res;
06937 }

static int vm_forwardoptions ( struct ast_channel chan,
struct ast_vm_user vmu,
char *  curdir,
int  curmsg,
char *  vmfmts,
char *  context,
signed char  record_gain,
long *  duration,
struct vm_state vms 
) [static]

Definition at line 3810 of file app_voicemail.c.

References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), config_text_file_save(), ast_vm_user::mailbox, make_file(), maxsilence, silencethreshold, and STORE.

Referenced by forward_message().

03812 {
03813    int cmd = 0;
03814    int retries = 0;
03815    signed char zero_gain = 0;
03816 
03817    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
03818       if (cmd)
03819          retries = 0;
03820       switch (cmd) {
03821       case '1': 
03822          /* prepend a message to the current message, update the metadata and return */
03823       {
03824          char msgfile[PATH_MAX];
03825          char textfile[PATH_MAX];
03826          int prepend_duration = 0;
03827          struct ast_config *msg_cfg;
03828          const char *duration_str;
03829 
03830          make_file(msgfile, sizeof(msgfile), curdir, curmsg);
03831          strcpy(textfile, msgfile);
03832          strncat(textfile, ".txt", sizeof(textfile) - 1);
03833          *duration = 0;
03834 
03835          /* if we can't read the message metadata, stop now */
03836          if (!(msg_cfg = ast_config_load(textfile))) {
03837             cmd = 0;
03838             break;
03839          }
03840 
03841          if (record_gain)
03842             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
03843 
03844          cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
03845          if (record_gain)
03846             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
03847 
03848          
03849          if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
03850             *duration = atoi(duration_str);
03851 
03852          if (prepend_duration) {
03853             struct ast_category *msg_cat;
03854             /* need enough space for a maximum-length message duration */
03855             char duration_str[12];
03856 
03857             *duration += prepend_duration;
03858             msg_cat = ast_category_get(msg_cfg, "message");
03859             snprintf(duration_str, 11, "%ld", *duration);
03860             if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
03861                config_text_file_save(textfile, msg_cfg, "app_voicemail");
03862                STORE(curdir, vmu->mailbox, context, curmsg, chan, vmu, vmfmts, *duration, vms);
03863             }
03864          }
03865 
03866          ast_config_destroy(msg_cfg);
03867 
03868          break;
03869       }
03870       case '2': 
03871          cmd = 't';
03872          break;
03873       case '*':
03874          cmd = '*';
03875          break;
03876       default: 
03877          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
03878             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
03879          if (!cmd)
03880             cmd = ast_play_and_wait(chan,"vm-starmain");
03881             /* "press star to return to the main menu" */
03882          if (!cmd)
03883             cmd = ast_waitfordigit(chan,6000);
03884          if (!cmd)
03885             retries++;
03886          if (retries > 3)
03887             cmd = 't';
03888       }
03889    }
03890    if (cmd == 't' || cmd == 'S')
03891       cmd = 0;
03892    return cmd;
03893 }

static int vm_instructions ( struct ast_channel chan,
struct vm_state vms,
int  skipadvanced 
) [static]

Definition at line 5823 of file app_voicemail.c.

References ast_play_and_wait(), ast_waitfordigit(), vm_state::curmsg, vm_state::deleted, vm_state::lastmsg, vm_state::repeats, vm_state::starting, vm_play_folder_name(), and vm_state::vmbox.

Referenced by vm_execmain().

05824 {
05825    int res = 0;
05826    /* Play instructions and wait for new command */
05827    while (!res) {
05828       if (vms->starting) {
05829          if (vms->lastmsg > -1) {
05830             res = ast_play_and_wait(chan, "vm-onefor");
05831             if (!res)
05832                res = vm_play_folder_name(chan, vms->vmbox);
05833          }
05834          if (!res)
05835             res = ast_play_and_wait(chan, "vm-opts");
05836       } else {
05837          if (vms->curmsg)
05838             res = ast_play_and_wait(chan, "vm-prev");
05839          if (!res && !skipadvanced)
05840             res = ast_play_and_wait(chan, "vm-advopts");
05841          if (!res)
05842             res = ast_play_and_wait(chan, "vm-repeat");
05843          if (!res && (vms->curmsg != vms->lastmsg))
05844             res = ast_play_and_wait(chan, "vm-next");
05845          if (!res) {
05846             if (!vms->deleted[vms->curmsg])
05847                res = ast_play_and_wait(chan, "vm-delete");
05848             else
05849                res = ast_play_and_wait(chan, "vm-undelete");
05850             if (!res)
05851                res = ast_play_and_wait(chan, "vm-toforward");
05852             if (!res)
05853                res = ast_play_and_wait(chan, "vm-savemessage");
05854          }
05855       }
05856       if (!res)
05857          res = ast_play_and_wait(chan, "vm-helpexit");
05858       if (!res)
05859          res = ast_waitfordigit(chan, 6000);
05860       if (!res) {
05861          vms->repeats++;
05862          if (vms->repeats > 2) {
05863             res = 't';
05864          }
05865       }
05866    }
05867    return res;
05868 }

static int vm_intro ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms 
) [static]

Definition at line 5778 of file app_voicemail.c.

References ast_fileexists(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, vm_state::username, vm_intro_cz(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_it(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_ru(), vm_intro_se(), vm_intro_ua(), VM_SPOOL_DIR, and VM_TEMPGREETWARN.

Referenced by vm_execmain().

05779 {
05780    char prefile[256];
05781    
05782    /* Notify the user that the temp greeting is set and give them the option to remove it */
05783    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
05784    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
05785       if (ast_fileexists(prefile, NULL, NULL) > 0)
05786          ast_play_and_wait(chan, "vm-tempgreetactive");
05787    }
05788 
05789    /* Play voicemail intro - syntax is different for different languages */
05790    if (!strcasecmp(chan->language, "de")) {  /* GERMAN syntax */
05791       return vm_intro_de(chan, vms);
05792    } else if (!strcasecmp(chan->language, "es")) { /* SPANISH syntax */
05793       return vm_intro_es(chan, vms);
05794    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN syntax */
05795       return vm_intro_it(chan, vms);
05796    } else if (!strcasecmp(chan->language, "fr")) { /* FRENCH syntax */
05797       return vm_intro_fr(chan, vms);
05798    } else if (!strcasecmp(chan->language, "nl")) { /* DUTCH syntax */
05799       return vm_intro_nl(chan, vms);
05800    } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE syntax */
05801       return vm_intro_pt(chan, vms);
05802    } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */
05803       return vm_intro_pt_BR(chan, vms);      
05804    } else if (!strcasecmp(chan->language, "cz")) { /* CZECH syntax */
05805       return vm_intro_cz(chan, vms);
05806    } else if (!strcasecmp(chan->language, "gr")) { /* GREEK syntax */
05807       return vm_intro_gr(chan, vms);
05808    } else if (!strcasecmp(chan->language, "pl")) { /* POLISH syntax */
05809       return vm_intro_pl(chan, vms);
05810    } else if (!strcasecmp(chan->language, "se")) { /* SWEDISH syntax */
05811       return vm_intro_se(chan, vms);
05812    } else if (!strcasecmp(chan->language, "no")) { /* NORWEGIAN syntax */
05813       return vm_intro_no(chan, vms);
05814    } else if (!strcasecmp(chan->language, "ru")) { /* RUSSIAN syntax */
05815       return vm_intro_ru(chan, vms);
05816    } else if (!strcasecmp(chan->language, "ua")) { /* UKRAINIAN syntax */
05817       return vm_intro_ua(chan, vms);
05818    } else {             /* Default to ENGLISH */
05819       return vm_intro_en(chan, vms);
05820    }
05821 }

static int vm_intro_cz ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5573 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05574 {
05575    int res;
05576    res = ast_play_and_wait(chan, "vm-youhave");
05577    if (!res) {
05578       if (vms->newmessages) {
05579          if (vms->newmessages == 1) {
05580             res = ast_play_and_wait(chan, "digits/jednu");
05581          } else {
05582             res = say_and_wait(chan, vms->newmessages, chan->language);
05583          }
05584          if (!res) {
05585             if ((vms->newmessages == 1))
05586                res = ast_play_and_wait(chan, "vm-novou");
05587             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
05588                res = ast_play_and_wait(chan, "vm-nove");
05589             if (vms->newmessages > 4)
05590                res = ast_play_and_wait(chan, "vm-novych");
05591          }
05592          if (vms->oldmessages && !res)
05593             res = ast_play_and_wait(chan, "vm-and");
05594          else if (!res) {
05595             if ((vms->newmessages == 1))
05596                res = ast_play_and_wait(chan, "vm-zpravu");
05597             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
05598                res = ast_play_and_wait(chan, "vm-zpravy");
05599             if (vms->newmessages > 4)
05600                res = ast_play_and_wait(chan, "vm-zprav");
05601          }
05602       }
05603       if (!res && vms->oldmessages) {
05604          res = say_and_wait(chan, vms->oldmessages, chan->language);
05605          if (!res) {
05606             if ((vms->oldmessages == 1))
05607                res = ast_play_and_wait(chan, "vm-starou");
05608             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
05609                res = ast_play_and_wait(chan, "vm-stare");
05610             if (vms->oldmessages > 4)
05611                res = ast_play_and_wait(chan, "vm-starych");
05612          }
05613          if (!res) {
05614             if ((vms->oldmessages == 1))
05615                res = ast_play_and_wait(chan, "vm-zpravu");
05616             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
05617                res = ast_play_and_wait(chan, "vm-zpravy");
05618             if (vms->oldmessages > 4)
05619                res = ast_play_and_wait(chan, "vm-zprav");
05620          }
05621       }
05622       if (!res) {
05623          if (!vms->oldmessages && !vms->newmessages) {
05624             res = ast_play_and_wait(chan, "vm-no");
05625             if (!res)
05626                res = ast_play_and_wait(chan, "vm-zpravy");
05627          }
05628       }
05629    }
05630    return res;
05631 }

static int vm_intro_de ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5266 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05267 {
05268    /* Introduce messages they have */
05269    int res;
05270    res = ast_play_and_wait(chan, "vm-youhave");
05271    if (!res) {
05272       if (vms->newmessages) {
05273          if ((vms->newmessages == 1))
05274             res = ast_play_and_wait(chan, "digits/1F");
05275          else
05276             res = say_and_wait(chan, vms->newmessages, chan->language);
05277          if (!res)
05278             res = ast_play_and_wait(chan, "vm-INBOX");
05279          if (vms->oldmessages && !res)
05280             res = ast_play_and_wait(chan, "vm-and");
05281          else if (!res) {
05282             if ((vms->newmessages == 1))
05283                res = ast_play_and_wait(chan, "vm-message");
05284             else
05285                res = ast_play_and_wait(chan, "vm-messages");
05286          }
05287             
05288       }
05289       if (!res && vms->oldmessages) {
05290          if (vms->oldmessages == 1)
05291             res = ast_play_and_wait(chan, "digits/1F");
05292          else
05293             res = say_and_wait(chan, vms->oldmessages, chan->language);
05294          if (!res)
05295             res = ast_play_and_wait(chan, "vm-Old");
05296          if (!res) {
05297             if (vms->oldmessages == 1)
05298                res = ast_play_and_wait(chan, "vm-message");
05299             else
05300                res = ast_play_and_wait(chan, "vm-messages");
05301          }
05302       }
05303       if (!res) {
05304          if (!vms->oldmessages && !vms->newmessages) {
05305             res = ast_play_and_wait(chan, "vm-no");
05306             if (!res)
05307                res = ast_play_and_wait(chan, "vm-messages");
05308          }
05309       }
05310    }
05311    return res;
05312 }

static int vm_intro_en ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5028 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05029 {
05030    int res;
05031 
05032    /* Introduce messages they have */
05033    res = ast_play_and_wait(chan, "vm-youhave");
05034    if (!res) {
05035       if (vms->newmessages) {
05036          res = say_and_wait(chan, vms->newmessages, chan->language);
05037          if (!res)
05038             res = ast_play_and_wait(chan, "vm-INBOX");
05039          if (vms->oldmessages && !res)
05040             res = ast_play_and_wait(chan, "vm-and");
05041          else if (!res) {
05042             if ((vms->newmessages == 1))
05043                res = ast_play_and_wait(chan, "vm-message");
05044             else
05045                res = ast_play_and_wait(chan, "vm-messages");
05046          }
05047             
05048       }
05049       if (!res && vms->oldmessages) {
05050          res = say_and_wait(chan, vms->oldmessages, chan->language);
05051          if (!res)
05052             res = ast_play_and_wait(chan, "vm-Old");
05053          if (!res) {
05054             if (vms->oldmessages == 1)
05055                res = ast_play_and_wait(chan, "vm-message");
05056             else
05057                res = ast_play_and_wait(chan, "vm-messages");
05058          }
05059       }
05060       if (!res) {
05061          if (!vms->oldmessages && !vms->newmessages) {
05062             res = ast_play_and_wait(chan, "vm-no");
05063             if (!res)
05064                res = ast_play_and_wait(chan, "vm-messages");
05065          }
05066       }
05067    }
05068    return res;
05069 }

static int vm_intro_es ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5315 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05316 {
05317    /* Introduce messages they have */
05318    int res;
05319    if (!vms->oldmessages && !vms->newmessages) {
05320       res = ast_play_and_wait(chan, "vm-youhaveno");
05321       if (!res)
05322          res = ast_play_and_wait(chan, "vm-messages");
05323    } else {
05324       res = ast_play_and_wait(chan, "vm-youhave");
05325    }
05326    if (!res) {
05327       if (vms->newmessages) {
05328          if (!res) {
05329             if ((vms->newmessages == 1)) {
05330                res = ast_play_and_wait(chan, "digits/1M");
05331                if (!res)
05332                   res = ast_play_and_wait(chan, "vm-message");
05333                if (!res)
05334                   res = ast_play_and_wait(chan, "vm-INBOXs");
05335             } else {
05336                res = say_and_wait(chan, vms->newmessages, chan->language);
05337                if (!res)
05338                   res = ast_play_and_wait(chan, "vm-messages");
05339                if (!res)
05340                   res = ast_play_and_wait(chan, "vm-INBOX");
05341             }
05342          }
05343          if (vms->oldmessages && !res)
05344             res = ast_play_and_wait(chan, "vm-and");
05345       }
05346       if (vms->oldmessages) {
05347          if (!res) {
05348             if (vms->oldmessages == 1) {
05349                res = ast_play_and_wait(chan, "digits/1M");
05350                if (!res)
05351                   res = ast_play_and_wait(chan, "vm-message");
05352                if (!res)
05353                   res = ast_play_and_wait(chan, "vm-Olds");
05354             } else {
05355                res = say_and_wait(chan, vms->oldmessages, chan->language);
05356                if (!res)
05357                   res = ast_play_and_wait(chan, "vm-messages");
05358                if (!res)
05359                   res = ast_play_and_wait(chan, "vm-Old");
05360             }
05361          }
05362       }
05363    }
05364 return res;
05365 }

static int vm_intro_fr ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5416 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05417 {
05418    /* Introduce messages they have */
05419    int res;
05420    res = ast_play_and_wait(chan, "vm-youhave");
05421    if (!res) {
05422       if (vms->newmessages) {
05423          res = say_and_wait(chan, vms->newmessages, chan->language);
05424          if (!res)
05425             res = ast_play_and_wait(chan, "vm-INBOX");
05426          if (vms->oldmessages && !res)
05427             res = ast_play_and_wait(chan, "vm-and");
05428          else if (!res) {
05429             if ((vms->newmessages == 1))
05430                res = ast_play_and_wait(chan, "vm-message");
05431             else
05432                res = ast_play_and_wait(chan, "vm-messages");
05433          }
05434             
05435       }
05436       if (!res && vms->oldmessages) {
05437          res = say_and_wait(chan, vms->oldmessages, chan->language);
05438          if (!res)
05439             res = ast_play_and_wait(chan, "vm-Old");
05440          if (!res) {
05441             if (vms->oldmessages == 1)
05442                res = ast_play_and_wait(chan, "vm-message");
05443             else
05444                res = ast_play_and_wait(chan, "vm-messages");
05445          }
05446       }
05447       if (!res) {
05448          if (!vms->oldmessages && !vms->newmessages) {
05449             res = ast_play_and_wait(chan, "vm-no");
05450             if (!res)
05451                res = ast_play_and_wait(chan, "vm-messages");
05452          }
05453       }
05454    }
05455    return res;
05456 }

static int vm_intro_gr ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 4990 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_intro().

04991 {
04992    int res = 0;
04993 
04994    if (vms->newmessages) {
04995       res = ast_play_and_wait(chan, "vm-youhave");
04996       if (!res) 
04997          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
04998       if (!res) {
04999          if ((vms->newmessages == 1)) {
05000             res = ast_play_and_wait(chan, "vm-INBOX");
05001             if (!res)
05002                res = ast_play_and_wait(chan, "vm-message");
05003          } else {
05004             res = ast_play_and_wait(chan, "vm-INBOXs");
05005             if (!res)
05006                res = ast_play_and_wait(chan, "vm-messages");
05007          }
05008       }
05009    } else if (vms->oldmessages){
05010       res = ast_play_and_wait(chan, "vm-youhave");
05011       if (!res)
05012          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
05013       if ((vms->oldmessages == 1)){
05014          res = ast_play_and_wait(chan, "vm-Old");
05015          if (!res)
05016             res = ast_play_and_wait(chan, "vm-message");
05017       } else {
05018          res = ast_play_and_wait(chan, "vm-Olds");
05019          if (!res)
05020             res = ast_play_and_wait(chan, "vm-messages");
05021       }
05022    } else if (!vms->oldmessages && !vms->newmessages) 
05023       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
05024    return res;
05025 }

static int vm_intro_it ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5072 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05073 {
05074    /* Introduce messages they have */
05075    int res;
05076    if (!vms->oldmessages && !vms->newmessages)
05077       res = ast_play_and_wait(chan, "vm-no") ||
05078          ast_play_and_wait(chan, "vm-message");
05079    else
05080       res = ast_play_and_wait(chan, "vm-youhave");
05081    if (!res && vms->newmessages) {
05082       res = (vms->newmessages == 1) ?
05083          ast_play_and_wait(chan, "digits/un") ||
05084          ast_play_and_wait(chan, "vm-nuovo") ||
05085          ast_play_and_wait(chan, "vm-message") :
05086          /* 2 or more new messages */
05087          say_and_wait(chan, vms->newmessages, chan->language) ||
05088          ast_play_and_wait(chan, "vm-nuovi") ||
05089          ast_play_and_wait(chan, "vm-messages");
05090       if (!res && vms->oldmessages)
05091          res = ast_play_and_wait(chan, "vm-and");
05092    }
05093    if (!res && vms->oldmessages) {
05094       res = (vms->oldmessages == 1) ?
05095          ast_play_and_wait(chan, "digits/un") ||
05096          ast_play_and_wait(chan, "vm-vecchio") ||
05097          ast_play_and_wait(chan, "vm-message") :
05098          /* 2 or more old messages */
05099          say_and_wait(chan, vms->oldmessages, chan->language) ||
05100          ast_play_and_wait(chan, "vm-vecchi") ||
05101          ast_play_and_wait(chan, "vm-messages");
05102    }
05103    return res ? -1 : 0;
05104 }

static int vm_intro_nl ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5459 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05460 {
05461    /* Introduce messages they have */
05462    int res;
05463    res = ast_play_and_wait(chan, "vm-youhave");
05464    if (!res) {
05465       if (vms->newmessages) {
05466          res = say_and_wait(chan, vms->newmessages, chan->language);
05467          if (!res) {
05468             if (vms->newmessages == 1)
05469                res = ast_play_and_wait(chan, "vm-INBOXs");
05470             else
05471                res = ast_play_and_wait(chan, "vm-INBOX");
05472          }
05473          if (vms->oldmessages && !res)
05474             res = ast_play_and_wait(chan, "vm-and");
05475          else if (!res) {
05476             if ((vms->newmessages == 1))
05477                res = ast_play_and_wait(chan, "vm-message");
05478             else
05479                res = ast_play_and_wait(chan, "vm-messages");
05480          }
05481             
05482       }
05483       if (!res && vms->oldmessages) {
05484          res = say_and_wait(chan, vms->oldmessages, chan->language);
05485          if (!res) {
05486             if (vms->oldmessages == 1)
05487                res = ast_play_and_wait(chan, "vm-Olds");
05488             else
05489                res = ast_play_and_wait(chan, "vm-Old");
05490          }
05491          if (!res) {
05492             if (vms->oldmessages == 1)
05493                res = ast_play_and_wait(chan, "vm-message");
05494             else
05495                res = ast_play_and_wait(chan, "vm-messages");
05496          }
05497       }
05498       if (!res) {
05499          if (!vms->oldmessages && !vms->newmessages) {
05500             res = ast_play_and_wait(chan, "vm-no");
05501             if (!res)
05502                res = ast_play_and_wait(chan, "vm-messages");
05503          }
05504       }
05505    }
05506    return res;
05507 }

static int vm_intro_no ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5222 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05223 {
05224    /* Introduce messages they have */
05225    int res;
05226 
05227    res = ast_play_and_wait(chan, "vm-youhave");
05228    if (res)
05229       return res;
05230 
05231    if (!vms->oldmessages && !vms->newmessages) {
05232       res = ast_play_and_wait(chan, "vm-no");
05233       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05234       return res;
05235    }
05236 
05237    if (vms->newmessages) {
05238       if ((vms->newmessages == 1)) {
05239          res = ast_play_and_wait(chan, "digits/1");
05240          res = res ? res : ast_play_and_wait(chan, "vm-ny");
05241          res = res ? res : ast_play_and_wait(chan, "vm-message");
05242       } else {
05243          res = say_and_wait(chan, vms->newmessages, chan->language);
05244          res = res ? res : ast_play_and_wait(chan, "vm-nye");
05245          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05246       }
05247       if (!res && vms->oldmessages)
05248          res = ast_play_and_wait(chan, "vm-and");
05249    }
05250    if (!res && vms->oldmessages) {
05251       if (vms->oldmessages == 1) {
05252          res = ast_play_and_wait(chan, "digits/1");
05253          res = res ? res : ast_play_and_wait(chan, "vm-gamel");
05254          res = res ? res : ast_play_and_wait(chan, "vm-message");
05255       } else {
05256          res = say_and_wait(chan, vms->oldmessages, chan->language);
05257          res = res ? res : ast_play_and_wait(chan, "vm-gamle");
05258          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05259       }
05260    }
05261 
05262    return res;
05263 }

static int vm_intro_pl ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5107 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05108 {
05109    /* Introduce messages they have */
05110    int res;
05111    div_t num;
05112 
05113    if (!vms->oldmessages && !vms->newmessages) {
05114       res = ast_play_and_wait(chan, "vm-no");
05115       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05116       return res;
05117    } else {
05118       res = ast_play_and_wait(chan, "vm-youhave");
05119    }
05120 
05121    if (vms->newmessages) {
05122       num = div(vms->newmessages, 10);
05123       if (vms->newmessages == 1) {
05124          res = ast_play_and_wait(chan, "digits/1-a");
05125          res = res ? res : ast_play_and_wait(chan, "vm-new-a");
05126          res = res ? res : ast_play_and_wait(chan, "vm-message");
05127       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05128          if (num.rem == 2) {
05129             if (!num.quot) {
05130                res = ast_play_and_wait(chan, "digits/2-ie");
05131             } else {
05132                res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
05133                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05134             }
05135          } else {
05136             res = say_and_wait(chan, vms->newmessages, chan->language);
05137          }
05138          res = res ? res : ast_play_and_wait(chan, "vm-new-e");
05139          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05140       } else {
05141          res = say_and_wait(chan, vms->newmessages, chan->language);
05142          res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
05143          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05144       }
05145       if (!res && vms->oldmessages)
05146          res = ast_play_and_wait(chan, "vm-and");
05147    }
05148    if (!res && vms->oldmessages) {
05149       num = div(vms->oldmessages, 10);
05150       if (vms->oldmessages == 1) {
05151          res = ast_play_and_wait(chan, "digits/1-a");
05152          res = res ? res : ast_play_and_wait(chan, "vm-old-a");
05153          res = res ? res : ast_play_and_wait(chan, "vm-message");
05154       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05155          if (num.rem == 2) {
05156             if (!num.quot) {
05157                res = ast_play_and_wait(chan, "digits/2-ie");
05158             } else {
05159                res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
05160                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05161             }
05162          } else {
05163             res = say_and_wait(chan, vms->oldmessages, chan->language);
05164          }
05165          res = res ? res : ast_play_and_wait(chan, "vm-old-e");
05166          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05167       } else {
05168          res = say_and_wait(chan, vms->oldmessages, chan->language);
05169          res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
05170          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05171       }
05172    }
05173 
05174    return res;
05175 }

static int vm_intro_pt ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5510 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_intro().

05511 {
05512    /* Introduce messages they have */
05513    int res;
05514    res = ast_play_and_wait(chan, "vm-youhave");
05515    if (!res) {
05516       if (vms->newmessages) {
05517          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
05518          if (!res) {
05519             if ((vms->newmessages == 1)) {
05520                res = ast_play_and_wait(chan, "vm-message");
05521                if (!res)
05522                   res = ast_play_and_wait(chan, "vm-INBOXs");
05523             } else {
05524                res = ast_play_and_wait(chan, "vm-messages");
05525                if (!res)
05526                   res = ast_play_and_wait(chan, "vm-INBOX");
05527             }
05528          }
05529          if (vms->oldmessages && !res)
05530             res = ast_play_and_wait(chan, "vm-and");
05531       }
05532       if (!res && vms->oldmessages) {
05533          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
05534          if (!res) {
05535             if (vms->oldmessages == 1) {
05536                res = ast_play_and_wait(chan, "vm-message");
05537                if (!res)
05538                   res = ast_play_and_wait(chan, "vm-Olds");
05539             } else {
05540                res = ast_play_and_wait(chan, "vm-messages");
05541                if (!res)
05542                   res = ast_play_and_wait(chan, "vm-Old");
05543             }
05544          }
05545       }
05546       if (!res) {
05547          if (!vms->oldmessages && !vms->newmessages) {
05548             res = ast_play_and_wait(chan, "vm-no");
05549             if (!res)
05550                res = ast_play_and_wait(chan, "vm-messages");
05551          }
05552       }
05553    }
05554    return res;
05555 }

static int vm_intro_pt_BR ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5368 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_intro().

05368                                                                          {
05369    /* Introduce messages they have */
05370    int res;
05371    if (!vms->oldmessages && !vms->newmessages) {
05372       res = ast_play_and_wait(chan, "vm-nomessages");
05373       return res;
05374    }
05375    else {
05376       res = ast_play_and_wait(chan, "vm-youhave");
05377    }
05378    if (vms->newmessages) {
05379       if (!res)
05380          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
05381       if ((vms->newmessages == 1)) {
05382          if (!res)
05383             res = ast_play_and_wait(chan, "vm-message");
05384          if (!res)
05385             res = ast_play_and_wait(chan, "vm-INBOXs");
05386       }
05387       else {
05388          if (!res)
05389             res = ast_play_and_wait(chan, "vm-messages");
05390          if (!res)
05391             res = ast_play_and_wait(chan, "vm-INBOX");
05392       }
05393       if (vms->oldmessages && !res)
05394          res = ast_play_and_wait(chan, "vm-and");
05395    }
05396    if (vms->oldmessages) {
05397       if (!res)
05398          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
05399       if (vms->oldmessages == 1) {
05400          if (!res)
05401             res = ast_play_and_wait(chan, "vm-message");
05402          if (!res)
05403             res = ast_play_and_wait(chan, "vm-Olds");
05404       }
05405       else {
05406          if (!res)
05407       res = ast_play_and_wait(chan, "vm-messages");
05408          if (!res)
05409             res = ast_play_and_wait(chan, "vm-Old");
05410       }
05411    }
05412    return res;
05413 }

static int vm_intro_ru ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5639 of file app_voicemail.c.

References ast_play_and_wait(), get_lastdigits(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05640 {
05641    int res;
05642    int lastnum = 0;
05643    int dcnum;
05644 
05645    res = ast_play_and_wait(chan, "vm-youhave");
05646    if (!res && vms->newmessages) {
05647       lastnum = get_lastdigits(vms->newmessages);
05648       dcnum = vms->newmessages - lastnum;
05649       if (dcnum)
05650          res = say_and_wait(chan, dcnum, chan->language);
05651       if (!res && lastnum) {
05652          if (lastnum == 1) 
05653             res = ast_play_and_wait(chan, "digits/ru/odno");
05654          else
05655             res = say_and_wait(chan, lastnum, chan->language);
05656       }
05657 
05658       if (!res)
05659          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-novoe" : "vm-novyh");
05660 
05661       if (!res && vms->oldmessages)
05662          res = ast_play_and_wait(chan, "vm-and");
05663    }
05664 
05665    if (!res && vms->oldmessages) {
05666       lastnum = get_lastdigits(vms->oldmessages);
05667       dcnum = vms->oldmessages - lastnum;
05668       if (dcnum)
05669          res = say_and_wait(chan, dcnum, chan->language);
05670       if (!res && lastnum) {
05671          if (lastnum == 1) 
05672             res = ast_play_and_wait(chan, "digits/ru/odno");
05673          else
05674             res = say_and_wait(chan, lastnum, chan->language);
05675       }
05676 
05677       if (!res)
05678          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-staroe" : "vm-staryh");
05679    }
05680 
05681    if (!res && !vms->newmessages && !vms->oldmessages) {
05682       lastnum = 0;
05683       res = ast_play_and_wait(chan, "vm-no");
05684    }
05685 
05686    if (!res) {
05687       switch (lastnum) {
05688       case 1:
05689          res = ast_play_and_wait(chan, "vm-soobshenie");
05690          break;
05691       case 2:
05692       case 3:
05693       case 4:
05694          res = ast_play_and_wait(chan, "vm-soobsheniya");
05695          break;
05696       default:
05697          res = ast_play_and_wait(chan, "vm-soobsheniy");
05698          break;
05699       }
05700    }
05701 
05702    return res;
05703 }

static int vm_intro_se ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5178 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05179 {
05180    /* Introduce messages they have */
05181    int res;
05182 
05183    res = ast_play_and_wait(chan, "vm-youhave");
05184    if (res)
05185       return res;
05186 
05187    if (!vms->oldmessages && !vms->newmessages) {
05188       res = ast_play_and_wait(chan, "vm-no");
05189       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05190       return res;
05191    }
05192 
05193    if (vms->newmessages) {
05194       if ((vms->newmessages == 1)) {
05195          res = ast_play_and_wait(chan, "digits/ett");
05196          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
05197          res = res ? res : ast_play_and_wait(chan, "vm-message");
05198       } else {
05199          res = say_and_wait(chan, vms->newmessages, chan->language);
05200          res = res ? res : ast_play_and_wait(chan, "vm-nya");
05201          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05202       }
05203       if (!res && vms->oldmessages)
05204          res = ast_play_and_wait(chan, "vm-and");
05205    }
05206    if (!res && vms->oldmessages) {
05207       if (vms->oldmessages == 1) {
05208          res = ast_play_and_wait(chan, "digits/ett");
05209          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
05210          res = res ? res : ast_play_and_wait(chan, "vm-message");
05211       } else {
05212          res = say_and_wait(chan, vms->oldmessages, chan->language);
05213          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
05214          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05215       }
05216    }
05217 
05218    return res;
05219 }

static int vm_intro_ua ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5713 of file app_voicemail.c.

References ast_play_and_wait(), get_lastdigits(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05714 {
05715    int res;
05716    int lastnum = 0;
05717    int dcnum;
05718 
05719    res = ast_play_and_wait(chan, "vm-youhave");
05720    if (!res && vms->newmessages) {
05721       lastnum = get_lastdigits(vms->newmessages);
05722       dcnum = vms->newmessages - lastnum;
05723       if (dcnum)
05724          res = say_and_wait(chan, dcnum, chan->language);
05725       if (!res && lastnum) {
05726          if (lastnum == 1) 
05727             res = ast_play_and_wait(chan, "digits/ua/1e");
05728          else
05729             res = say_and_wait(chan, lastnum, chan->language);
05730       }
05731 
05732       if (!res)
05733          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-nove" : "vm-INBOX");
05734 
05735       if (!res && vms->oldmessages)
05736          res = ast_play_and_wait(chan, "vm-and");
05737    }
05738 
05739    if (!res && vms->oldmessages) {
05740       lastnum = get_lastdigits(vms->oldmessages);
05741       dcnum = vms->oldmessages - lastnum;
05742       if (dcnum)
05743          res = say_and_wait(chan, dcnum, chan->language);
05744       if (!res && lastnum) {
05745          if (lastnum == 1) 
05746             res = ast_play_and_wait(chan, "digits/ua/1e");
05747          else
05748             res = say_and_wait(chan, lastnum, chan->language);
05749       }
05750 
05751       if (!res)
05752          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-stare" : "vm-Old");
05753    }
05754 
05755    if (!res && !vms->newmessages && !vms->oldmessages) {
05756       lastnum = 0;
05757       res = ast_play_and_wait(chan, "vm-no");
05758    }
05759 
05760    if (!res) {
05761       switch (lastnum) {
05762       case 1:
05763       case 2:
05764       case 3:
05765       case 4:
05766          res = ast_play_and_wait(chan, "vm-message");
05767          break;
05768       default:
05769          res = ast_play_and_wait(chan, "vm-messages");
05770          break;
05771       }
05772    }
05773 
05774    return res;
05775 }

static int vm_lock_path ( const char *  path  )  [static]

Definition at line 943 of file app_voicemail.c.

References ast_lock_path(), and AST_LOCK_TIMEOUT.

Referenced by close_mailbox(), copy_message(), count_messages(), last_message_index(), leave_voicemail(), resequence_mailbox(), and save_to_folder().

00944 {
00945    switch (ast_lock_path(path)) {
00946    case AST_LOCK_TIMEOUT:
00947       return -1;
00948    default:
00949       return 0;
00950    }
00951 }

static FILE* vm_mkftemp ( char *  template  )  [static]

Definition at line 1755 of file app_voicemail.c.

References my_umask, and VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

01756 {
01757    FILE *p = NULL;
01758    int pfd = mkstemp(template);
01759    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
01760    if (pfd > -1) {
01761       p = fdopen(pfd, "w+");
01762       if (!p) {
01763          close(pfd);
01764          pfd = -1;
01765       }
01766    }
01767    return p;
01768 }

static int vm_newuser ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
char *  fmtc,
signed char  record_gain 
) [static]

Definition at line 5870 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_fileexists(), ast_log(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_flag, ast_vm_user::context, ext_pass_cmd, LOG_DEBUG, LOG_NOTICE, maxgreet, option_debug, play_record_review(), vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, VM_FORCENAME, and VM_SPOOL_DIR.

Referenced by vm_execmain().

05871 {
05872    int cmd = 0;
05873    int duration = 0;
05874    int tries = 0;
05875    char newpassword[80] = "";
05876    char newpassword2[80] = "";
05877    char prefile[PATH_MAX] = "";
05878    unsigned char buf[256];
05879    int bytes=0;
05880 
05881    if (ast_adsi_available(chan)) {
05882       bytes += adsi_logo(buf + bytes);
05883       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
05884       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
05885       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05886       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05887       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05888    }
05889 
05890    /* First, have the user change their password 
05891       so they won't get here again */
05892    for (;;) {
05893       newpassword[1] = '\0';
05894       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
05895       if (cmd == '#')
05896          newpassword[0] = '\0';
05897       if (cmd < 0 || cmd == 't' || cmd == '#')
05898          return cmd;
05899       cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
05900       if (cmd < 0 || cmd == 't' || cmd == '#')
05901          return cmd;
05902       newpassword2[1] = '\0';
05903       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
05904       if (cmd == '#')
05905          newpassword2[0] = '\0';
05906       if (cmd < 0 || cmd == 't' || cmd == '#')
05907          return cmd;
05908       cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
05909       if (cmd < 0 || cmd == 't' || cmd == '#')
05910          return cmd;
05911       if (!strcmp(newpassword, newpassword2))
05912          break;
05913       ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
05914       cmd = ast_play_and_wait(chan, "vm-mismatch");
05915       if (++tries == 3)
05916          return -1;
05917    }
05918    if (ast_strlen_zero(ext_pass_cmd)) 
05919       vm_change_password(vmu,newpassword);
05920    else 
05921       vm_change_password_shell(vmu,newpassword);
05922    if (option_debug > 2)
05923       ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
05924    cmd = ast_play_and_wait(chan,"vm-passchanged");
05925 
05926    /* If forcename is set, have the user record their name */  
05927    if (ast_test_flag(vmu, VM_FORCENAME)) {
05928       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
05929       if (ast_fileexists(prefile, NULL, NULL) < 1) {
05930 #ifndef IMAP_STORAGE
05931          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05932 #else
05933          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05934 #endif
05935          if (cmd < 0 || cmd == 't' || cmd == '#')
05936             return cmd;
05937       }
05938    }
05939 
05940    /* If forcegreetings is set, have the user record their greetings */
05941    if (ast_test_flag(vmu, VM_FORCEGREET)) {
05942       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
05943       if (ast_fileexists(prefile, NULL, NULL) < 1) {
05944 #ifndef IMAP_STORAGE
05945          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05946 #else
05947          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05948 #endif
05949          if (cmd < 0 || cmd == 't' || cmd == '#')
05950             return cmd;
05951       }
05952 
05953       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
05954       if (ast_fileexists(prefile, NULL, NULL) < 1) {
05955 #ifndef IMAP_STORAGE
05956          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05957 #else
05958          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05959 #endif
05960          if (cmd < 0 || cmd == 't' || cmd == '#')
05961             return cmd;
05962       }
05963    }
05964 
05965    return cmd;
05966 }

static int vm_options ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
char *  fmtc,
signed char  record_gain 
) [static]

Definition at line 5968 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_log(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_waitfordigit(), ast_vm_user::context, ext_pass_cmd, LOG_DEBUG, LOG_NOTICE, maxgreet, option_debug, ast_vm_user::password, play_record_review(), vm_state::username, vm_change_password(), vm_change_password_shell(), VM_SPOOL_DIR, and vm_tempgreeting().

Referenced by vm_execmain().

05969 {
05970    int cmd = 0;
05971    int retries = 0;
05972    int duration = 0;
05973    char newpassword[80] = "";
05974    char newpassword2[80] = "";
05975    char prefile[PATH_MAX] = "";
05976    unsigned char buf[256];
05977    int bytes=0;
05978 
05979    if (ast_adsi_available(chan))
05980    {
05981       bytes += adsi_logo(buf + bytes);
05982       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
05983       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
05984       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05985       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05986       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05987    }
05988    while ((cmd >= 0) && (cmd != 't')) {
05989       if (cmd)
05990          retries = 0;
05991       switch (cmd) {
05992       case '1':
05993          snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
05994 #ifndef IMAP_STORAGE
05995          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05996 #else
05997          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05998 #endif
05999          break;
06000       case '2': 
06001          snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06002 #ifndef IMAP_STORAGE
06003          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06004 #else
06005          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06006 #endif
06007          break;
06008       case '3': 
06009          snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06010 #ifndef IMAP_STORAGE
06011          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06012 #else
06013          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06014 #endif
06015          break;
06016       case '4': 
06017          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
06018          break;
06019       case '5':
06020          if (vmu->password[0] == '-') {
06021             cmd = ast_play_and_wait(chan, "vm-no");
06022             break;
06023          }
06024          newpassword[1] = '\0';
06025          newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06026          if (cmd == '#')
06027             newpassword[0] = '\0';
06028          else {
06029             if (cmd < 0)
06030                break;
06031             if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
06032                break;
06033             }
06034          }
06035          newpassword2[1] = '\0';
06036          newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06037          if (cmd == '#')
06038             newpassword2[0] = '\0';
06039          else {
06040             if (cmd < 0)
06041                break;
06042 
06043             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#"))) {
06044                break;
06045             }
06046          }
06047          if (strcmp(newpassword, newpassword2)) {
06048             ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
06049             cmd = ast_play_and_wait(chan, "vm-mismatch");
06050             break;
06051          }
06052          if (ast_strlen_zero(ext_pass_cmd)) 
06053             vm_change_password(vmu,newpassword);
06054          else 
06055             vm_change_password_shell(vmu,newpassword);
06056          if (option_debug > 2)
06057             ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
06058          cmd = ast_play_and_wait(chan,"vm-passchanged");
06059          break;
06060       case '*': 
06061          cmd = 't';
06062          break;
06063       default: 
06064          cmd = ast_play_and_wait(chan,"vm-options");
06065          if (!cmd)
06066             cmd = ast_waitfordigit(chan,6000);
06067          if (!cmd)
06068             retries++;
06069          if (retries > 3)
06070             cmd = 't';
06071       }
06072    }
06073    if (cmd == 't')
06074       cmd = 0;
06075    return cmd;
06076 }

static int vm_play_folder_name ( struct ast_channel chan,
char *  mbox 
) [static]

Definition at line 4959 of file app_voicemail.c.

References ast_play_and_wait(), vm_play_folder_name_gr(), vm_play_folder_name_pl(), and vm_play_folder_name_ua().

Referenced by get_folder(), vm_execmain(), and vm_instructions().

04960 {
04961    int cmd;
04962 
04963    if (!strcasecmp(chan->language, "it") || !strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) { /* Italian, Spanish, French or Portuguese syntax */
04964       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
04965       return cmd ? cmd : ast_play_and_wait(chan, mbox);
04966    } else if (!strcasecmp(chan->language, "gr")){
04967       return vm_play_folder_name_gr(chan, mbox);
04968    } else if (!strcasecmp(chan->language, "pl")){
04969       return vm_play_folder_name_pl(chan, mbox);
04970    } else if (!strcasecmp(chan->language, "ua")){  /* Ukrainian syntax */
04971       return vm_play_folder_name_ua(chan, mbox);
04972    } else {  /* Default English */
04973       cmd = ast_play_and_wait(chan, mbox);
04974       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
04975    }
04976 }

static int vm_play_folder_name_gr ( struct ast_channel chan,
char *  mbox 
) [static]

Definition at line 4912 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

04913 {
04914    int cmd;
04915    char *buf;
04916 
04917    buf = alloca(strlen(mbox)+2); 
04918    strcpy(buf, mbox);
04919    strcat(buf,"s");
04920 
04921    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
04922       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
04923       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
04924    } else {
04925       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
04926       return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
04927    }
04928 }

static int vm_play_folder_name_pl ( struct ast_channel chan,
char *  mbox 
) [static]

Definition at line 4930 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

04931 {
04932    int cmd;
04933 
04934    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
04935       if (!strcasecmp(mbox, "vm-INBOX"))
04936          cmd = ast_play_and_wait(chan, "vm-new-e");
04937       else
04938          cmd = ast_play_and_wait(chan, "vm-old-e");
04939       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
04940    } else {
04941       cmd = ast_play_and_wait(chan, "vm-messages");
04942       return cmd ? cmd : ast_play_and_wait(chan, mbox);
04943    }
04944 }

static int vm_play_folder_name_ua ( struct ast_channel chan,
char *  mbox 
) [static]

Definition at line 4946 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

04947 {
04948    int cmd;
04949 
04950    if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")){
04951       cmd = ast_play_and_wait(chan, "vm-messages");
04952       return cmd ? cmd : ast_play_and_wait(chan, mbox);
04953    } else {
04954       cmd = ast_play_and_wait(chan, mbox);
04955       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
04956    }
04957 }

static int vm_tempgreeting ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
char *  fmtc,
signed char  record_gain 
) [static]

Definition at line 6078 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_fileexists(), ast_log(), ast_play_and_wait(), ast_waitfordigit(), ast_vm_user::context, create_dirpath(), DELETE, DISPOSE, LOG_WARNING, maxgreet, play_record_review(), RETRIEVE, vm_state::username, and VM_SPOOL_DIR.

Referenced by vm_options().

06079 {
06080    int res;
06081    int cmd = 0;
06082    int retries = 0;
06083    int duration = 0;
06084    char prefile[PATH_MAX] = "";
06085    unsigned char buf[256];
06086    char dest[PATH_MAX];
06087    int bytes = 0;
06088 
06089    if (ast_adsi_available(chan)) {
06090       bytes += adsi_logo(buf + bytes);
06091       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
06092       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06093       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06094       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06095       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06096    }
06097 
06098    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06099    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
06100       ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
06101       return -1;
06102    }
06103    while ((cmd >= 0) && (cmd != 't')) {
06104       if (cmd)
06105          retries = 0;
06106       RETRIEVE(prefile, -1);
06107       if (ast_fileexists(prefile, NULL, NULL) <= 0) {
06108 #ifndef IMAP_STORAGE
06109          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06110 #else
06111          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06112 #endif
06113          cmd = 't';  
06114       } else {
06115          switch (cmd) {
06116          case '1':
06117 #ifndef IMAP_STORAGE
06118             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06119 #else
06120             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06121 #endif
06122             break;
06123          case '2':
06124             DELETE(prefile, -1, prefile);
06125             ast_play_and_wait(chan, "vm-tempremoved");
06126             cmd = 't';  
06127             break;
06128          case '*': 
06129             cmd = 't';
06130             break;
06131          default:
06132             cmd = ast_play_and_wait(chan,
06133                ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
06134                   "vm-tempgreeting2" : "vm-tempgreeting");
06135             if (!cmd)
06136                cmd = ast_waitfordigit(chan,6000);
06137             if (!cmd)
06138                retries++;
06139             if (retries > 3)
06140                cmd = 't';
06141          }
06142       }
06143       DISPOSE(prefile, -1);
06144    }
06145    if (cmd == 't')
06146       cmd = 0;
06147    return cmd;
06148 }

static int vmauthenticate ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 7129 of file app_voicemail.c.

References AST_MAX_EXTENSION, ast_module_user_add, ast_module_user_remove, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_vm_user::context, pbx_builtin_setvar_helper(), s, strsep(), and vm_authenticate().

Referenced by load_module().

07130 {
07131    struct ast_module_user *u;
07132    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
07133    struct ast_vm_user vmus;
07134    char *options = NULL;
07135    int silent = 0, skipuser = 0;
07136    int res = -1;
07137 
07138    u = ast_module_user_add(chan);
07139    
07140    if (s) {
07141       s = ast_strdupa(s);
07142       user = strsep(&s, "|");
07143       options = strsep(&s, "|");
07144       if (user) {
07145          s = user;
07146          user = strsep(&s, "@");
07147          context = strsep(&s, "");
07148          if (!ast_strlen_zero(user))
07149             skipuser++;
07150          ast_copy_string(mailbox, user, sizeof(mailbox));
07151       }
07152    }
07153 
07154    if (options) {
07155       silent = (strchr(options, 's')) != NULL;
07156    }
07157 
07158    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
07159       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
07160       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
07161       ast_play_and_wait(chan, "auth-thankyou");
07162       res = 0;
07163    }
07164 
07165    ast_module_user_remove(u);
07166    return res;
07167 }

static struct tm* vmu_tm ( const struct ast_vm_user vmu,
struct tm *  tm 
) [static, read]

Definition at line 1735 of file app_voicemail.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_strlen_zero(), t, and ast_vm_user::zonetag.

Referenced by make_email_file(), and sendpage().

01736 {
01737    const struct vm_zone *z = NULL;
01738    time_t t = time(NULL);
01739 
01740    /* Does this user have a timezone specified? */
01741    if (!ast_strlen_zero(vmu->zonetag)) {
01742       /* Find the zone in the list */
01743       AST_LIST_LOCK(&zones);
01744       AST_LIST_TRAVERSE(&zones, z, list) {
01745          if (!strcmp(z->name, vmu->zonetag))
01746             break;
01747       }
01748       AST_LIST_UNLOCK(&zones);
01749    }
01750    ast_localtime(&t, tm, z ? z->timezone : NULL);
01751    return tm;
01752 }

static int wait_file ( struct ast_channel chan,
struct vm_state vms,
char *  file 
) [static]

Definition at line 4218 of file app_voicemail.c.

References ast_control_streamfile(), and skipms.

04219 {
04220    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
04221 }

static int wait_file2 ( struct ast_channel chan,
struct vm_state vms,
char *  file 
) [static]

Definition at line 4210 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_log(), ast_stream_and_wait(), and LOG_WARNING.

Referenced by play_message(), play_message_callerid(), and play_message_duration().

04211 {
04212    int res;
04213    if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0) 
04214       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
04215    return res;
04216 }


Variable Documentation

char* addesc = "Comedian Mail" [static]

Definition at line 436 of file app_voicemail.c.

Referenced by adsi_load_vmail().

unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static]

Definition at line 556 of file app_voicemail.c.

Referenced by adsi_begin(), adsi_load_vmail(), and load_config().

unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC" [static]

Definition at line 557 of file app_voicemail.c.

Referenced by adsi_load_vmail(), and load_config().

int adsiver = 1 [static]

Definition at line 558 of file app_voicemail.c.

Referenced by adsi_begin(), adsi_load_vmail(), and load_config().

char* app = "VoiceMail" [static]

Definition at line 511 of file app_voicemail.c.

char* app2 = "VoiceMailMain" [static]

Definition at line 514 of file app_voicemail.c.

char* app3 = "MailboxExists" [static]

Definition at line 516 of file app_voicemail.c.

char* app4 = "VMAuthenticate" [static]

Definition at line 517 of file app_voicemail.c.

char callcontext[AST_MAX_CONTEXT] [static]

Definition at line 541 of file app_voicemail.c.

Referenced by load_config(), and populate_defaults().

char charset[32] = "ISO-8859-1" [static]

Definition at line 554 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static]

Definition at line 544 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

Initial value:

 {
   { "show", "voicemail", "users", NULL },
   handle_voicemail_show_users, NULL,
   NULL, complete_voicemail_show_users }

Definition at line 7271 of file app_voicemail.c.

Initial value:

 {
   { "show", "voicemail", "zones", NULL },
   handle_voicemail_show_zones, NULL,
   NULL, NULL }

Definition at line 7276 of file app_voicemail.c.

struct ast_cli_entry cli_voicemail[] [static]

Definition at line 7281 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char* descrip_vm [static]

Definition at line 441 of file app_voicemail.c.

Referenced by load_module().

char* descrip_vm_box_exists [static]

Definition at line 486 of file app_voicemail.c.

Referenced by load_module().

char* descrip_vmain [static]

Definition at line 468 of file app_voicemail.c.

Referenced by load_module().

char* descrip_vmauthenticate [static]

Definition at line 500 of file app_voicemail.c.

Referenced by load_module().

char dialcontext[AST_MAX_CONTEXT] [static]

Definition at line 540 of file app_voicemail.c.

Referenced by directory_exec(), load_config(), and populate_defaults().

char* emailbody = NULL [static]

Definition at line 547 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char emaildateformat[32] = "%A, %B %d, %Y at %r" [static]

Definition at line 559 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char* emailsubject = NULL [static]

Definition at line 548 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char emailtitle[100] [static]

Definition at line 553 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char exitcontext[AST_MAX_CONTEXT] [static]

Definition at line 542 of file app_voicemail.c.

Referenced by conf_run(), load_config(), and populate_defaults().

char ext_pass_cmd[128] [static]

Definition at line 422 of file app_voicemail.c.

Referenced by load_config(), vm_change_password_shell(), vm_newuser(), and vm_options().

char externnotify[160] [static]

Definition at line 526 of file app_voicemail.c.

Referenced by load_config(), and run_externnotify().

char fromstring[100] [static]

Definition at line 551 of file app_voicemail.c.

Referenced by load_config(), make_email_file(), and sendpage().

struct ast_flags globalflags = {0} [static]

Definition at line 536 of file app_voicemail.c.

char mailcmd[160] [static]

Definition at line 525 of file app_voicemail.c.

int maxgreet [static]

Definition at line 532 of file app_voicemail.c.

Referenced by load_config(), vm_newuser(), vm_options(), and vm_tempgreeting().

int maxlogins [static]

Definition at line 534 of file app_voicemail.c.

Referenced by load_config(), and vm_execmain().

int maxmsg [static]

Definition at line 522 of file app_voicemail.c.

int maxsilence [static]

int my_umask

Definition at line 424 of file app_voicemail.c.

Referenced by leave_voicemail(), load_module(), make_email_file(), and vm_mkftemp().

char* pagerbody = NULL [static]

Definition at line 549 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

char pagerfromstring[100] [static]

Definition at line 552 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

char* pagersubject = NULL [static]

Definition at line 550 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

int saydurationminfo [static]

Definition at line 538 of file app_voicemail.c.

Referenced by load_config(), and populate_defaults().

char serveremail[80] [static]

Definition at line 524 of file app_voicemail.c.

int silencethreshold = 128 [static]

Definition at line 523 of file app_voicemail.c.

int skipms [static]

struct ast_smdi_interface* smdi_iface = NULL [static]

Definition at line 527 of file app_voicemail.c.

Referenced by load_config(), and run_externnotify().

char* synopsis_vm [static]

Initial value:

"Leave a Voicemail message"

Definition at line 438 of file app_voicemail.c.

Referenced by load_module().

char* synopsis_vm_box_exists [static]

Initial value:

"Check to see if Voicemail mailbox exists"

Definition at line 483 of file app_voicemail.c.

Referenced by load_module().

char* synopsis_vmain [static]

Initial value:

"Check Voicemail messages"

Definition at line 465 of file app_voicemail.c.

Referenced by load_module().

char* synopsis_vmauthenticate [static]

Initial value:

"Authenticate with Voicemail passwords"

Definition at line 497 of file app_voicemail.c.

Referenced by load_module().

char userscontext[AST_MAX_EXTENSION] = "default" [static]

Definition at line 434 of file app_voicemail.c.

Referenced by load_config().

enum { ... } vm_option_args

enum { ... } vm_option_flags

char VM_SPOOL_DIR[PATH_MAX] [static]

char vmfmts[80] [static]

Definition at line 528 of file app_voicemail.c.

Referenced by forward_message(), leave_voicemail(), load_config(), and vm_execmain().

int vmmaxmessage [static]

Definition at line 531 of file app_voicemail.c.

Referenced by leave_voicemail(), and load_config().

int vmminmessage [static]

Definition at line 530 of file app_voicemail.c.

Referenced by leave_voicemail(), and load_config().

char voicemail_show_users_help[] [static]

Initial value:

"Usage: voicemail show users [for <context>]\n"
"       Lists all mailboxes currently set up\n"

Definition at line 7169 of file app_voicemail.c.

char voicemail_show_zones_help[] [static]

Initial value:

"Usage: voicemail show zones\n"
"       Lists zone message formats\n"

Definition at line 7173 of file app_voicemail.c.

double volgain [static]

Definition at line 529 of file app_voicemail.c.


Generated on Sat Apr 12 07:12:33 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.5