Sun Jun 12 16:37:51 2011

Asterisk developer's documentation


app_voicemail_odbc.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_odbc.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_plain_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 ERROR_MAILBOX_FULL   -200
#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 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 void copy_plain_file (char *frompath, char *topath)
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, struct ast_vm_user *vmu, 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_greeting (struct ast_channel *chan, struct ast_vm_user *vmu, char *filename, char *ecodes)
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_odbc.c.


Define Documentation

#define ASTERISK_USERNAME   "asterisk"

Definition at line 165 of file app_voicemail_odbc.c.

#define BASELINELEN   72

Definition at line 181 of file app_voicemail_odbc.c.

#define BASEMAXINLINE   256

Definition at line 182 of file app_voicemail_odbc.c.

#define BASEMAXINLINE   256

Definition at line 182 of file app_voicemail_odbc.c.

#define CHUNKSIZE   65536

Definition at line 162 of file app_voicemail_odbc.c.

#define COMMAND_TIMEOUT   5000

Definition at line 158 of file app_voicemail_odbc.c.

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

Definition at line 427 of file app_voicemail_odbc.c.

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

Definition at line 428 of file app_voicemail_odbc.c.

#define DISPOSE ( a,
 ) 

Definition at line 423 of file app_voicemail_odbc.c.

#define ENDL   "\n"

#define eol   "\r\n"

Definition at line 183 of file app_voicemail_odbc.c.

#define ERROR_LOCK_PATH   -100

Definition at line 204 of file app_voicemail_odbc.c.

#define ERROR_MAILBOX_FULL   -200

Definition at line 205 of file app_voicemail_odbc.c.

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

Definition at line 425 of file app_voicemail_odbc.c.

#define INTRO   "vm-intro"

Definition at line 171 of file app_voicemail_odbc.c.

#define MAX_DATETIME_FORMAT   512

Definition at line 185 of file app_voicemail_odbc.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 186 of file app_voicemail_odbc.c.

#define MAXMSG   100

Definition at line 173 of file app_voicemail_odbc.c.

#define MAXMSGLIMIT   9999

Definition at line 175 of file app_voicemail_odbc.c.

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

Definition at line 426 of file app_voicemail_odbc.c.

#define RETRIEVE ( a,
 ) 

Definition at line 422 of file app_voicemail_odbc.c.

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

Definition at line 169 of file app_voicemail_odbc.c.

#define SMDI_MWI_WAIT_TIMEOUT   1000

Definition at line 156 of file app_voicemail_odbc.c.

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

Definition at line 424 of file app_voicemail_odbc.c.

#define tdesc   "Comedian Mail (Voicemail System)"

Definition at line 443 of file app_voicemail_odbc.c.

#define VM_ALLOCED   (1 << 13)

Definition at line 201 of file app_voicemail_odbc.c.

#define VM_ATTACH   (1 << 11)

Definition at line 199 of file app_voicemail_odbc.c.

#define VM_DELETE   (1 << 12)

Definition at line 200 of file app_voicemail_odbc.c.

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 198 of file app_voicemail_odbc.c.

#define VM_ENVELOPE   (1 << 4)

Definition at line 192 of file app_voicemail_odbc.c.

#define VM_FORCEGREET   (1 << 8)

Have new users record their greetings

Definition at line 196 of file app_voicemail_odbc.c.

#define VM_FORCENAME   (1 << 7)

Have new users record their name

Definition at line 195 of file app_voicemail_odbc.c.

#define VM_OPERATOR   (1 << 1)

Definition at line 189 of file app_voicemail_odbc.c.

#define VM_PBXSKIP   (1 << 9)

Definition at line 197 of file app_voicemail_odbc.c.

#define VM_REVIEW   (1 << 0)

Definition at line 188 of file app_voicemail_odbc.c.

#define VM_SAYCID   (1 << 2)

Definition at line 190 of file app_voicemail_odbc.c.

#define VM_SAYDURATION   (1 << 5)

Definition at line 193 of file app_voicemail_odbc.c.

#define VM_SEARCH   (1 << 14)

Definition at line 202 of file app_voicemail_odbc.c.

#define VM_SKIPAFTERCMD   (1 << 6)

Definition at line 194 of file app_voicemail_odbc.c.

#define VM_SVMAIL   (1 << 3)

Definition at line 191 of file app_voicemail_odbc.c.

#define VM_TEMPGREETWARN   (1 << 15)

Remind user tempgreeting is set

Definition at line 203 of file app_voicemail_odbc.c.

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 164 of file app_voicemail_odbc.c.

#define VOICEMAIL_DIR_MODE   0777

Definition at line 160 of file app_voicemail_odbc.c.

#define VOICEMAIL_FILE_MODE   0666

Definition at line 161 of file app_voicemail_odbc.c.


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 208 of file app_voicemail_odbc.c.

00208      {
00209    OPT_SILENT =           (1 << 0),
00210    OPT_BUSY_GREETING =    (1 << 1),
00211    OPT_UNAVAIL_GREETING = (1 << 2),
00212    OPT_RECORDGAIN =       (1 << 3),
00213    OPT_PREPEND_MAILBOX =  (1 << 4),
00214    OPT_PRIORITY_JUMP =    (1 << 5),
00215    OPT_AUTOPLAY =         (1 << 6),
00216 } vm_option_flags;

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_ARRAY_SIZE 

Definition at line 218 of file app_voicemail_odbc.c.

00218      {
00219    OPT_ARG_RECORDGAIN = 0,
00220    OPT_ARG_PLAYFOLDER = 1,
00221    /* This *must* be the last value in this enum! */
00222    OPT_ARG_ARRAY_SIZE = 2,
00223 } vm_option_args;


Function Documentation

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

Definition at line 2671 of file app_voicemail_odbc.c.

References ast_strlen_zero().

02672 {
02673    DIR *dir;
02674    struct dirent *de;
02675    char fn[256];
02676    int ret = 0;
02677    if (!folder)
02678       folder = "INBOX";
02679    /* If no mailbox, return immediately */
02680    if (ast_strlen_zero(mailbox))
02681       return 0;
02682    if (!context)
02683       context = "default";
02684    snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
02685    dir = opendir(fn);
02686    if (!dir)
02687       return 0;
02688    while ((de = readdir(dir))) {
02689       if (!strncasecmp(de->d_name, "msg", 3)) {
02690          if (shortcircuit) {
02691             ret = 1;
02692             break;
02693          } else if (!strncasecmp(de->d_name + 8, "txt", 3))
02694             ret++;
02695       }
02696    }
02697    closedir(dir);
02698    return ret;
02699 }

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

Definition at line 3437 of file app_voicemail_odbc.c.

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

03438 {
03439    int x;
03440    if (!ast_adsi_available(chan))
03441       return;
03442    x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
03443    if (x < 0)
03444       return;
03445    if (!x) {
03446       if (adsi_load_vmail(chan, useadsi)) {
03447          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
03448          return;
03449       }
03450    } else
03451       *useadsi = 1;
03452 }

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

Definition at line 3624 of file app_voicemail_odbc.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.

03625 {
03626    int bytes=0;
03627    unsigned char buf[256];
03628    unsigned char keys[8];
03629 
03630    int x;
03631 
03632    if (!ast_adsi_available(chan))
03633       return;
03634 
03635    /* New meaning for keys */
03636    for (x=0;x<5;x++)
03637       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
03638 
03639    keys[6] = 0x0;
03640    keys[7] = 0x0;
03641 
03642    if (!vms->curmsg) {
03643       /* No prev key, provide "Folder" instead */
03644       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03645    }
03646    if (vms->curmsg >= vms->lastmsg) {
03647       /* If last message ... */
03648       if (vms->curmsg) {
03649          /* but not only message, provide "Folder" instead */
03650          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03651       } else {
03652          /* Otherwise if only message, leave blank */
03653          keys[3] = 1;
03654       }
03655    }
03656 
03657    /* If deleted, show "undeleted" */
03658    if (vms->deleted[vms->curmsg]) 
03659       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
03660 
03661    /* Except "Exit" */
03662    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
03663    bytes += ast_adsi_set_keys(buf + bytes, keys);
03664    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03665 
03666    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03667 }

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

Definition at line 3502 of file app_voicemail_odbc.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.

03503 {
03504    unsigned char buf[256];
03505    int bytes=0;
03506    unsigned char keys[8];
03507    int x,y;
03508 
03509    if (!ast_adsi_available(chan))
03510       return;
03511 
03512    for (x=0;x<5;x++) {
03513       y = ADSI_KEY_APPS + 12 + start + x;
03514       if (y > ADSI_KEY_APPS + 12 + 4)
03515          y = 0;
03516       keys[x] = ADSI_KEY_SKT | y;
03517    }
03518    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
03519    keys[6] = 0;
03520    keys[7] = 0;
03521 
03522    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
03523    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
03524    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03525    bytes += ast_adsi_set_keys(buf + bytes, keys);
03526    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03527 
03528    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03529 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

Definition at line 3772 of file app_voicemail_odbc.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().

03773 {
03774    unsigned char buf[256];
03775    int bytes=0;
03776 
03777    if (!ast_adsi_available(chan))
03778       return;
03779    bytes += adsi_logo(buf + bytes);
03780    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
03781    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
03782    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03783    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03784 
03785    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03786 }

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

Definition at line 3306 of file app_voicemail_odbc.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, 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.

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

static void adsi_login ( struct ast_channel chan  )  [static]

Definition at line 3454 of file app_voicemail_odbc.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.

03455 {
03456    unsigned char buf[256];
03457    int bytes=0;
03458    unsigned char keys[8];
03459    int x;
03460    if (!ast_adsi_available(chan))
03461       return;
03462 
03463    for (x=0;x<8;x++)
03464       keys[x] = 0;
03465    /* Set one key for next */
03466    keys[3] = ADSI_KEY_APPS + 3;
03467 
03468    bytes += adsi_logo(buf + bytes);
03469    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
03470    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
03471    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03472    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
03473    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
03474    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
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 int adsi_logo ( unsigned char *  buf  )  [static]

Definition at line 3298 of file app_voicemail_odbc.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, and ast_adsi_display().

03299 {
03300    int bytes = 0;
03301    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
03302    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
03303    return bytes;
03304 }

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

Definition at line 3531 of file app_voicemail_odbc.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().

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

static void adsi_password ( struct ast_channel chan  )  [static]

Definition at line 3480 of file app_voicemail_odbc.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.

03481 {
03482    unsigned char buf[256];
03483    int bytes=0;
03484    unsigned char keys[8];
03485    int x;
03486    if (!ast_adsi_available(chan))
03487       return;
03488 
03489    for (x=0;x<8;x++)
03490       keys[x] = 0;
03491    /* Set one key for next */
03492    keys[3] = ADSI_KEY_APPS + 3;
03493 
03494    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03495    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
03496    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
03497    bytes += ast_adsi_set_keys(buf + bytes, keys);
03498    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03499    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03500 }

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

Definition at line 3669 of file app_voicemail_odbc.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.

03670 {
03671    unsigned char buf[256] = "";
03672    char buf1[256] = "", buf2[256] = "";
03673    int bytes=0;
03674    unsigned char keys[8];
03675    int x;
03676 
03677    char *newm = (vms->newmessages == 1) ? "message" : "messages";
03678    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
03679    if (!ast_adsi_available(chan))
03680       return;
03681    if (vms->newmessages) {
03682       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
03683       if (vms->oldmessages) {
03684          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
03685          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
03686       } else {
03687          snprintf(buf2, sizeof(buf2), "%s.", newm);
03688       }
03689    } else if (vms->oldmessages) {
03690       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
03691       snprintf(buf2, sizeof(buf2), "%s.", oldm);
03692    } else {
03693       strcpy(buf1, "You have no messages.");
03694       buf2[0] = ' ';
03695       buf2[1] = '\0';
03696    }
03697    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03698    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03699    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03700 
03701    for (x=0;x<6;x++)
03702       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03703    keys[6] = 0;
03704    keys[7] = 0;
03705 
03706    /* Don't let them listen if there are none */
03707    if (vms->lastmsg < 0)
03708       keys[0] = 1;
03709    bytes += ast_adsi_set_keys(buf + bytes, keys);
03710 
03711    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03712 
03713    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03714 }

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

Definition at line 3716 of file app_voicemail_odbc.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.

03717 {
03718    unsigned char buf[256] = "";
03719    char buf1[256] = "", buf2[256] = "";
03720    int bytes=0;
03721    unsigned char keys[8];
03722    int x;
03723 
03724    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
03725 
03726    if (!ast_adsi_available(chan))
03727       return;
03728 
03729    /* Original command keys */
03730    for (x=0;x<6;x++)
03731       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03732 
03733    keys[6] = 0;
03734    keys[7] = 0;
03735 
03736    if ((vms->lastmsg + 1) < 1)
03737       keys[0] = 0;
03738 
03739    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
03740       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
03741 
03742    if (vms->lastmsg + 1)
03743       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
03744    else
03745       strcpy(buf2, "no messages.");
03746    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03747    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03748    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
03749    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03750    bytes += ast_adsi_set_keys(buf + bytes, keys);
03751 
03752    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03753 
03754    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03755    
03756 }

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 8030 of file app_voicemail_odbc.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().

08031 {
08032    int res = 0;
08033 #ifdef IMAP_STORAGE
08034    char origtimeS[256],cidS[256],contextS[256];
08035    char *header_content,*temp;
08036 #endif
08037    char filename[PATH_MAX];
08038    struct ast_config *msg_cfg = NULL;
08039    const char *origtime, *context;
08040    char *cid, *name, *num;
08041    int retries = 0;
08042 
08043    vms->starting = 0; 
08044 #ifdef IMAP_STORAGE
08045    /* START HERE */
08046    /* get the message info!! */
08047    if (option_debug > 2)
08048       ast_log (LOG_DEBUG,"Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n",vms->curmsg, vms->msgArray[vms->curmsg]);
08049    if (vms->msgArray[vms->curmsg] == 0) {
08050       ast_log (LOG_WARNING,"Trying to access unknown message\n");
08051       return -1;
08052    }
08053 
08054    /* This will only work for new messages... */
08055    header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
08056    /* empty string means no valid header */
08057    if (ast_strlen_zero(header_content)) {
08058       ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
08059       return -1;
08060    }
08061 
08062    /* Get info from headers!! */
08063    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Caller-ID-Num:");
08064    
08065    if (temp)
08066       ast_copy_string(cidS,temp, sizeof(cidS));
08067    else
08068       cidS[0] = '\0';
08069    
08070    cid = &cidS[0];
08071    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Context:");
08072    
08073    if (temp)
08074       ast_copy_string(contextS,temp, sizeof(contextS));
08075    else
08076       contextS[0] = '\0';
08077    
08078    context = &contextS[0];
08079    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Orig-time:");
08080    
08081    if (temp)
08082       ast_copy_string(origtimeS,temp, sizeof(origtimeS));
08083    else
08084       origtimeS[0] = '\0';
08085    
08086    origtime = &origtimeS[0];
08087    
08088    ast_copy_string(filename, "IMAP_STORAGE", sizeof(filename));
08089 #else
08090    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08091 
08092    /* Retrieve info from VM attribute file */
08093 
08094    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
08095    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
08096    RETRIEVE(vms->curdir, vms->curmsg);
08097    msg_cfg = ast_config_load(filename);
08098    DISPOSE(vms->curdir, vms->curmsg);
08099    if (!msg_cfg) {
08100       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
08101       return 0;
08102    }
08103 
08104    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
08105       ast_config_destroy(msg_cfg);
08106       return 0;
08107    }
08108 
08109    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
08110 
08111    context = ast_variable_retrieve(msg_cfg, "message", "context");
08112    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
08113       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
08114 #endif
08115    switch (option) {
08116    case 3:
08117       if (!res)
08118          res = play_message_datetime(chan, vmu, origtime, filename);
08119       if (!res)
08120          res = play_message_callerid(chan, vms, cid, context, 0);
08121 
08122       res = 't';
08123       break;
08124 
08125    case 2:  /* Call back */
08126 
08127       if (ast_strlen_zero(cid))
08128          break;
08129 
08130       ast_callerid_parse(cid, &name, &num);
08131       while ((res > -1) && (res != 't')) {
08132          switch (res) {
08133          case '1':
08134             if (num) {
08135                /* Dial the CID number */
08136                res = dialout(chan, vmu, num, vmu->callback);
08137                if (res) {
08138                   ast_config_destroy(msg_cfg);
08139                   return 9;
08140                }
08141             } else {
08142                res = '2';
08143             }
08144             break;
08145 
08146          case '2':
08147             /* Want to enter a different number, can only do this if there's a dialout context for this user */
08148             if (!ast_strlen_zero(vmu->dialout)) {
08149                res = dialout(chan, vmu, NULL, vmu->dialout);
08150                if (res) {
08151                   ast_config_destroy(msg_cfg);
08152                   return 9;
08153                }
08154             } else {
08155                if (option_verbose > 2)
08156                   ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
08157                res = ast_play_and_wait(chan, "vm-sorry");
08158             }
08159             ast_config_destroy(msg_cfg);
08160             return res;
08161          case '*':
08162             res = 't';
08163             break;
08164          case '3':
08165          case '4':
08166          case '5':
08167          case '6':
08168          case '7':
08169          case '8':
08170          case '9':
08171          case '0':
08172 
08173             res = ast_play_and_wait(chan, "vm-sorry");
08174             retries++;
08175             break;
08176          default:
08177             if (num) {
08178                if (option_verbose > 2)
08179                   ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
08180                res = ast_play_and_wait(chan, "vm-num-i-have");
08181                if (!res)
08182                   res = play_message_callerid(chan, vms, num, vmu->context, 1);
08183                if (!res)
08184                   res = ast_play_and_wait(chan, "vm-tocallnum");
08185                /* Only prompt for a caller-specified number if there is a dialout context specified */
08186                if (!ast_strlen_zero(vmu->dialout)) {
08187                   if (!res)
08188                      res = ast_play_and_wait(chan, "vm-calldiffnum");
08189                }
08190             } else {
08191                res = ast_play_and_wait(chan, "vm-nonumber");
08192                if (!ast_strlen_zero(vmu->dialout)) {
08193                   if (!res)
08194                      res = ast_play_and_wait(chan, "vm-toenternumber");
08195                }
08196             }
08197             if (!res)
08198                res = ast_play_and_wait(chan, "vm-star-cancel");
08199             if (!res)
08200                res = ast_waitfordigit(chan, 6000);
08201             if (!res) {
08202                retries++;
08203                if (retries > 3)
08204                   res = 't';
08205             }
08206             break; 
08207             
08208          }
08209          if (res == 't')
08210             res = 0;
08211          else if (res == '*')
08212             res = -1;
08213       }
08214       break;
08215       
08216    case 1:  /* Reply */
08217       /* Send reply directly to sender */
08218       if (ast_strlen_zero(cid))
08219          break;
08220 
08221       ast_callerid_parse(cid, &name, &num);
08222       if (!num) {
08223          if (option_verbose > 2)
08224             ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
08225          if (!res)
08226             res = ast_play_and_wait(chan, "vm-nonumber");
08227          ast_config_destroy(msg_cfg);
08228          return res;
08229       } else {
08230          struct ast_vm_user vmu2;
08231          if (find_user(&vmu2, vmu->context, num)) {
08232             struct leave_vm_options leave_options;
08233             char mailbox[AST_MAX_EXTENSION * 2 + 2];
08234             snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
08235 
08236             if (option_verbose > 2)
08237                ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
08238             
08239             memset(&leave_options, 0, sizeof(leave_options));
08240             leave_options.record_gain = record_gain;
08241             res = leave_voicemail(chan, mailbox, &leave_options);
08242             if (!res)
08243                res = 't';
08244             ast_config_destroy(msg_cfg);
08245             return res;
08246          } else {
08247             /* Sender has no mailbox, can't reply */
08248             if (option_verbose > 2)
08249                ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
08250             ast_play_and_wait(chan, "vm-nobox");
08251             res = 't';
08252             ast_config_destroy(msg_cfg);
08253             return res;
08254          }
08255       } 
08256       res = 0;
08257 
08258       break;
08259    }
08260 
08261 #ifndef IMAP_STORAGE
08262    ast_config_destroy(msg_cfg);
08263 
08264    if (!res) {
08265       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08266       vms->heard[msg] = 1;
08267       res = wait_file(chan, vms, vms->fn);
08268    }
08269 #endif
08270    return res;
08271 }

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

Definition at line 7133 of file app_voicemail_odbc.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().

07134 {
07135    /* Assumes lock is already held */
07136    char *tmp;
07137    char *stringp;
07138    char *s;
07139    struct ast_vm_user *vmu;
07140 
07141    tmp = ast_strdupa(data);
07142 
07143    if ((vmu = find_or_create(context, mbox))) {
07144       populate_defaults(vmu);
07145 
07146       stringp = tmp;
07147       if ((s = strsep(&stringp, ","))) 
07148          ast_copy_string(vmu->password, s, sizeof(vmu->password));
07149       if (stringp && (s = strsep(&stringp, ","))) 
07150          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
07151       if (stringp && (s = strsep(&stringp, ","))) 
07152          ast_copy_string(vmu->email, s, sizeof(vmu->email));
07153       if (stringp && (s = strsep(&stringp, ","))) 
07154          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
07155       if (stringp && (s = strsep(&stringp, ","))) 
07156          apply_options(vmu, s);
07157    }
07158    return 0;
07159 }

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

Definition at line 588 of file app_voicemail_odbc.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.

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

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

Definition at line 671 of file app_voicemail_odbc.c.

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

00672 {  /* Destructively Parse options and apply */
00673    char *stringp;
00674    char *s;
00675    char *var, *value;
00676    stringp = ast_strdupa(options);
00677    while ((s = strsep(&stringp, "|"))) {
00678       value = s;
00679       if ((var = strsep(&value, "=")) && value) {
00680          apply_option(vmu, var, value);
00681       }
00682    }  
00683 }

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

Definition at line 685 of file app_voicemail_odbc.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.

00686 {
00687    struct ast_variable *tmp;
00688    tmp = var;
00689    while (tmp) {
00690       if (!strcasecmp(tmp->name, "vmsecret")) {
00691          ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00692       } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
00693          if (ast_strlen_zero(retval->password))
00694             ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00695       } else if (!strcasecmp(tmp->name, "uniqueid")) {
00696          ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00697       } else if (!strcasecmp(tmp->name, "pager")) {
00698          ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00699       } else if (!strcasecmp(tmp->name, "email")) {
00700          ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00701       } else if (!strcasecmp(tmp->name, "fullname")) {
00702          ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00703       } else if (!strcasecmp(tmp->name, "context")) {
00704          ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00705 #ifdef IMAP_STORAGE
00706       } else if (!strcasecmp(tmp->name, "imapuser")) {
00707          ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
00708       } else if (!strcasecmp(tmp->name, "imappassword")) {
00709          ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
00710 #endif
00711       } else
00712          apply_option(retval, tmp->name, tmp->value);
00713       tmp = tmp->next;
00714    } 
00715 }

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 1641 of file app_voicemail_odbc.c.

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

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

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

Definition at line 655 of file app_voicemail_odbc.c.

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

00656 {
00657    int res;
00658    if (!ast_strlen_zero(vmu->uniqueid)) {
00659       res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL);
00660       if (res > 0) {
00661          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00662          res = 0;
00663       } else if (!res) {
00664          res = -1;
00665       }
00666       return res;
00667    }
00668    return -1;
00669 }

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

Definition at line 4907 of file app_voicemail_odbc.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, ERROR_MAILBOX_FULL, EXISTS, vm_state::fn, vm_state::fn2, vm_state::heard, vm_state::lastmsg, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, option_debug, RENAME, save_to_folder(), and vm_lock_path().

04908 {
04909    int x = 0;
04910 #ifndef IMAP_STORAGE
04911    int res = 0, nummsg;
04912 #endif
04913 
04914    if (vms->lastmsg <= -1)
04915       goto done;
04916 
04917    vms->curmsg = -1; 
04918 #ifndef IMAP_STORAGE
04919    /* Get the deleted messages fixed */ 
04920    if (vm_lock_path(vms->curdir))
04921       return ERROR_LOCK_PATH;
04922     
04923    for (x = 0; x < vmu->maxmsg; x++) { 
04924       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
04925          /* Save this message.  It's not in INBOX or hasn't been heard */ 
04926          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
04927          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
04928             break;
04929          vms->curmsg++; 
04930          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
04931          if (strcmp(vms->fn, vms->fn2)) { 
04932             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
04933          } 
04934       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
04935          /* Move to old folder before deleting */ 
04936          res = save_to_folder(vmu, vms, x, 1);
04937          if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) {
04938             /* If save failed do not delete the message */
04939             ast_log(LOG_WARNING, "Save failed.  Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
04940             vms->deleted[x] = 0;
04941             vms->heard[x] = 0;
04942             --x;
04943          } 
04944       } 
04945    } 
04946 
04947    /* Delete ALL remaining messages */
04948    nummsg = x - 1;
04949    for (x = vms->curmsg + 1; x <= nummsg; x++) {
04950       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
04951       if (EXISTS(vms->curdir, x, vms->fn, NULL))
04952          DELETE(vms->curdir, x, vms->fn);
04953    }
04954    ast_unlock_path(vms->curdir);
04955 #else
04956    if (vms->deleted) {
04957       for (x=0;x < vmu->maxmsg;x++) { 
04958          if (vms->deleted[x]) { 
04959             if (option_debug > 2)
04960                ast_log(LOG_DEBUG,"IMAP delete of %d\n",x);
04961             IMAP_DELETE(vms->curdir, x, vms->fn, vms);
04962          }
04963       }
04964    }
04965 #endif
04966 
04967 done:
04968    if (vms->deleted)
04969       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
04970    if (vms->heard)
04971       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
04972 
04973    return 0;
04974 }

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

Definition at line 7322 of file app_voicemail_odbc.c.

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

07323 {
07324    int which = 0;
07325    int wordlen;
07326    struct ast_vm_user *vmu;
07327    const char *context = "";
07328 
07329    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
07330    if (pos > 4)
07331       return NULL;
07332    if (pos == 3)
07333       return (state == 0) ? ast_strdup("for") : NULL;
07334    wordlen = strlen(word);
07335    AST_LIST_TRAVERSE(&users, vmu, list) {
07336       if (!strncasecmp(word, vmu->context, wordlen)) {
07337          if (context && strcmp(context, vmu->context) && ++which > state)
07338             return ast_strdup(vmu->context);
07339          /* ignore repeated contexts ? */
07340          context = vmu->context;
07341       }
07342    }
07343    return NULL;
07344 }

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

Definition at line 1519 of file app_voicemail_odbc.c.

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

01520 {
01521    int ifd;
01522    int ofd;
01523    int res;
01524    int len;
01525    char buf[4096];
01526 
01527 #ifdef HARDLINK_WHEN_POSSIBLE
01528    /* Hard link if possible; saves disk space & is faster */
01529    if (link(infile, outfile)) {
01530 #endif
01531       if ((ifd = open(infile, O_RDONLY)) < 0) {
01532          ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
01533          return -1;
01534       }
01535       if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
01536          ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
01537          close(ifd);
01538          return -1;
01539       }
01540       do {
01541          len = read(ifd, buf, sizeof(buf));
01542          if (len < 0) {
01543             ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
01544             close(ifd);
01545             close(ofd);
01546             unlink(outfile);
01547          }
01548          if (len) {
01549             res = write(ofd, buf, len);
01550             if (errno == ENOMEM || errno == ENOSPC || res != len) {
01551                ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
01552                close(ifd);
01553                close(ofd);
01554                unlink(outfile);
01555             }
01556          }
01557       } while (len);
01558       close(ifd);
01559       close(ofd);
01560       return 0;
01561 #ifdef HARDLINK_WHEN_POSSIBLE
01562    } else {
01563       /* Hard link succeeded */
01564       return 0;
01565    }
01566 #endif
01567 }

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 2626 of file app_voicemail_odbc.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(), mbox(), notify_new_message(), S_OR, and vm_lock_path().

02627 {
02628    char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
02629    const char *frombox = mbox(imbox);
02630    int recipmsgnum;
02631 
02632    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
02633 
02634    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
02635    
02636    if (!dir)
02637       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
02638    else
02639       ast_copy_string(fromdir, dir, sizeof(fromdir));
02640 
02641    make_file(frompath, sizeof(frompath), fromdir, msgnum);
02642 
02643    if (vm_lock_path(todir))
02644       return ERROR_LOCK_PATH;
02645 
02646    recipmsgnum = 0;
02647    do {
02648       make_file(topath, sizeof(topath), todir, recipmsgnum);
02649       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
02650          break;
02651       recipmsgnum++;
02652    } while (recipmsgnum < recip->maxmsg);
02653    if (recipmsgnum < recip->maxmsg) {
02654       COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
02655    } else {
02656       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
02657    }
02658    ast_unlock_path(todir);
02659    notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
02660    
02661    return 0;
02662 }

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

Definition at line 1569 of file app_voicemail_odbc.c.

References ast_filecopy(), and copy().

01570 {
01571    char frompath2[PATH_MAX], topath2[PATH_MAX];
01572    ast_filecopy(frompath, topath, NULL);
01573    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
01574    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
01575    copy(frompath2, topath2);
01576 }

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

Definition at line 1461 of file app_voicemail_odbc.c.

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

01462 {
01463    /* Find all .txt files - even if they are not in sequence from 0000 */
01464 
01465    int vmcount = 0;
01466    DIR *vmdir = NULL;
01467    struct dirent *vment = NULL;
01468 
01469    if (vm_lock_path(dir))
01470       return ERROR_LOCK_PATH;
01471 
01472    if ((vmdir = opendir(dir))) {
01473       while ((vment = readdir(vmdir))) {
01474          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
01475             vmcount++;
01476       }
01477       closedir(vmdir);
01478    }
01479    ast_unlock_path(dir);
01480    
01481    return vmcount;
01482 }

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 928 of file app_voicemail_odbc.c.

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

00929 {
00930    mode_t   mode = VOICEMAIL_DIR_MODE;
00931 
00932    if (!ast_strlen_zero(context)) {
00933       make_dir(dest, len, context, "", "");
00934       if (mkdir(dest, mode) && errno != EEXIST) {
00935          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00936          return -1;
00937       }
00938    }
00939    if (!ast_strlen_zero(ext)) {
00940       make_dir(dest, len, context, ext, "");
00941       if (mkdir(dest, mode) && errno != EEXIST) {
00942          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00943          return -1;
00944       }
00945    }
00946    if (!ast_strlen_zero(folder)) {
00947       make_dir(dest, len, context, ext, folder);
00948       if (mkdir(dest, mode) && errno != EEXIST) {
00949          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00950          return -1;
00951       }
00952    }
00953    return 0;
00954 }

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

Definition at line 7969 of file app_voicemail_odbc.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.

07970 {
07971    int cmd = 0;
07972    char destination[80] = "";
07973    int retries = 0;
07974 
07975    if (!num) {
07976       if (option_verbose > 2)
07977          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
07978       while (retries < 3 && cmd != 't') {
07979          destination[1] = '\0';
07980          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
07981          if (!cmd)
07982             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
07983          if (!cmd)
07984             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
07985          if (!cmd) {
07986             cmd = ast_waitfordigit(chan, 6000);
07987             if (cmd)
07988                destination[0] = cmd;
07989          }
07990          if (!cmd) {
07991             retries++;
07992          } else {
07993 
07994             if (cmd < 0)
07995                return 0;
07996             if (cmd == '*') {
07997                if (option_verbose > 2)
07998                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
07999                return 0;
08000             }
08001             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
08002                retries++;
08003             else
08004                cmd = 't';
08005          }
08006       }
08007       if (retries >= 3) {
08008          return 0;
08009       }
08010       
08011    } else {
08012       if (option_verbose > 2)
08013          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
08014       ast_copy_string(destination, num, sizeof(destination));
08015    }
08016 
08017    if (!ast_strlen_zero(destination)) {
08018       if (destination[strlen(destination) -1 ] == '*')
08019          return 0; 
08020       if (option_verbose > 2)
08021          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
08022       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
08023       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
08024       chan->priority = 0;
08025       return 9;
08026    }
08027    return 0;
08028 }

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

Definition at line 7113 of file app_voicemail_odbc.c.

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

07114 {
07115    struct ast_vm_user *vmu;
07116    AST_LIST_TRAVERSE(&users, vmu, list) {
07117       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox))
07118          break;
07119       if (context && (!strcasecmp(context, vmu->context)) && (!strcasecmp(mbox, vmu->mailbox)))
07120          break;
07121    }
07122    
07123    if (!vmu) {
07124       if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
07125          ast_copy_string(vmu->context, context, sizeof(vmu->context));
07126          ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
07127          AST_LIST_INSERT_TAIL(&users, vmu, list);
07128       }
07129    }
07130    return vmu;
07131 }

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

Definition at line 746 of file app_voicemail_odbc.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(), users, VM_ALLOCED, and VM_SEARCH.

00747 {
00748    /* This function could be made to generate one from a database, too */
00749    struct ast_vm_user *vmu=NULL, *cur;
00750    AST_LIST_LOCK(&users);
00751 
00752    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00753       context = "default";
00754 
00755    AST_LIST_TRAVERSE(&users, cur, list) {
00756       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00757          break;
00758       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00759          break;
00760    }
00761    if (cur) {
00762       /* Make a copy, so that on a reload, we have no race */
00763       if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
00764          memcpy(vmu, cur, sizeof(*vmu));
00765          ast_set2_flag(vmu, !ivm, VM_ALLOCED);
00766          AST_LIST_NEXT(vmu, list) = NULL;
00767       }
00768    } else
00769       vmu = find_user_realtime(ivm, context, mailbox);
00770    AST_LIST_UNLOCK(&users);
00771    return vmu;
00772 }

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

Definition at line 717 of file app_voicemail_odbc.c.

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

00718 {
00719    struct ast_variable *var;
00720    struct ast_vm_user *retval;
00721 
00722    if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
00723       if (!ivm)
00724          ast_set_flag(retval, VM_ALLOCED);   
00725       else
00726          memset(retval, 0, sizeof(*retval));
00727       if (mailbox) 
00728          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00729       populate_defaults(retval);
00730       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00731          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00732       else
00733          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00734       if (var) {
00735          apply_options_full(retval, var);
00736          ast_variables_destroy(var);
00737       } else { 
00738          if (!ivm) 
00739             free(retval);
00740          retval = NULL;
00741       }  
00742    } 
00743    return retval;
00744 }

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 3998 of file app_voicemail_odbc.c.

References 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_vm_user::context, ast_channel::context, copy_message(), copy_plain_file(), create_dirpath(), vm_state::curdir, vm_state::curmsg, ast_channel::exten, find_user(), vm_state::fn, free_user(), leave_voicemail(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_vm_user::mailbox, make_file(), option_debug, pbx_exec(), pbx_findapp(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, run_externnotify(), s, S_OR, sendmail(), STORE, strsep(), vm_state::username, username, VM_ATTACH, vm_delete(), VM_DIRECFORWARD, and vm_forwardoptions().

03999 {
04000 #ifdef IMAP_STORAGE
04001    BODY *body;
04002    char *header_content;
04003    char *temp;
04004    char todir[256];
04005    int todircount=0;
04006    struct vm_state *dstvms;
04007 #endif
04008    char username[70]="";
04009    int res = 0, cmd = 0;
04010    struct ast_vm_user *receiver = NULL, *vmtmp;
04011    AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
04012    char *stringp;
04013    const char *s;
04014    int saved_messages = 0, found = 0;
04015    int valid_extensions = 0;
04016    char *dir;
04017    int curmsg;
04018 
04019    if (vms == NULL) return -1;
04020    dir = vms->curdir;
04021    curmsg = vms->curmsg;
04022    
04023    while (!res && !valid_extensions) {
04024       int use_directory = 0;
04025       if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
04026          int done = 0;
04027          int retries = 0;
04028          cmd=0;
04029          while ((cmd >= 0) && !done ){
04030             if (cmd)
04031                retries = 0;
04032             switch (cmd) {
04033             case '1': 
04034                use_directory = 0;
04035                done = 1;
04036                break;
04037             case '2': 
04038                use_directory = 1;
04039                done=1;
04040                break;
04041             case '*': 
04042                cmd = 't';
04043                done = 1;
04044                break;
04045             default: 
04046                /* Press 1 to enter an extension press 2 to use the directory */
04047                cmd = ast_play_and_wait(chan,"vm-forward");
04048                if (!cmd)
04049                   cmd = ast_waitfordigit(chan,3000);
04050                if (!cmd)
04051                   retries++;
04052                if (retries > 3)
04053                {
04054                   cmd = 't';
04055                   done = 1;
04056                }
04057                
04058             }
04059          }
04060          if (cmd < 0 || cmd == 't')
04061             break;
04062       }
04063       
04064       if (use_directory) {
04065          /* use app_directory */
04066          
04067          char old_context[sizeof(chan->context)];
04068          char old_exten[sizeof(chan->exten)];
04069          int old_priority;
04070          struct ast_app* app;
04071 
04072          
04073          app = pbx_findapp("Directory");
04074          if (app) {
04075             char vmcontext[256];
04076             /* make backup copies */
04077             memcpy(old_context, chan->context, sizeof(chan->context));
04078             memcpy(old_exten, chan->exten, sizeof(chan->exten));
04079             old_priority = chan->priority;
04080             
04081             /* call the the Directory, changes the channel */
04082             snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default");
04083             res = pbx_exec(chan, app, vmcontext);
04084             
04085             ast_copy_string(username, chan->exten, sizeof(username));
04086             
04087             /* restore the old context, exten, and priority */
04088             memcpy(chan->context, old_context, sizeof(chan->context));
04089             memcpy(chan->exten, old_exten, sizeof(chan->exten));
04090             chan->priority = old_priority;
04091             
04092          } else {
04093             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
04094             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
04095          }
04096       } else {
04097          /* Ask for an extension */
04098          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
04099          if (res)
04100             break;
04101          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
04102             break;
04103       }
04104       
04105       /* start all over if no username */
04106       if (ast_strlen_zero(username))
04107          continue;
04108       stringp = username;
04109       s = strsep(&stringp, "*");
04110       /* start optimistic */
04111       valid_extensions = 1;
04112       while (s) {
04113          /* Don't forward to ourselves but allow leaving a message for ourselves (flag == 1).  find_user is going to malloc since we have a NULL as first argument */
04114          if ((flag == 1 || strcmp(s,sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
04115             AST_LIST_INSERT_HEAD(&extensions, receiver, list);
04116             found++;
04117          } else {
04118             valid_extensions = 0;
04119             break;
04120          }
04121          s = strsep(&stringp, "*");
04122       }
04123       /* break from the loop of reading the extensions */
04124       if (valid_extensions)
04125          break;
04126       /* "I am sorry, that's not a valid extension.  Please try again." */
04127       res = ast_play_and_wait(chan, "pbx-invalid");
04128    }
04129    /* check if we're clear to proceed */
04130    if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
04131       return res;
04132    if (flag==1) {
04133       struct leave_vm_options leave_options;
04134       char mailbox[AST_MAX_EXTENSION * 2 + 2];
04135       /* Make sure that context doesn't get set as a literal "(null)" (or else find_user won't find it) */
04136       if (context)
04137          snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
04138       else
04139          ast_copy_string(mailbox, username, sizeof(mailbox));
04140 
04141       /* Send VoiceMail */
04142       memset(&leave_options, 0, sizeof(leave_options));
04143       leave_options.record_gain = record_gain;
04144       cmd = leave_voicemail(chan, mailbox, &leave_options);
04145    } else {
04146       /* Forward VoiceMail */
04147       long duration = 0;
04148       char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
04149       struct vm_state vmstmp;
04150 
04151       memcpy(&vmstmp, vms, sizeof(vmstmp));
04152 
04153       make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
04154       create_dirpath(vmstmp.curdir, sizeof(vmstmp.curdir), sender->context, vmstmp.username, "tmp");
04155       make_file(msgfile, sizeof(msgfile), vmstmp.curdir, curmsg);
04156 
04157       RETRIEVE(dir, curmsg);
04158 
04159       /* Alter a surrogate file, only */
04160       copy_plain_file(origmsgfile, msgfile);
04161 
04162       cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp);
04163       if (!cmd) {
04164          AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
04165 #ifdef IMAP_STORAGE
04166             char *myserveremail;
04167             int attach_user_voicemail;
04168             /* Need to get message content */
04169             if (option_debug > 2)
04170                ast_log (LOG_DEBUG, "Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n", vms->curmsg, vms->msgArray[vms->curmsg]);
04171             if (vms->msgArray[vms->curmsg] == 0) {
04172                ast_log (LOG_WARNING,"Trying to access unknown message\n");
04173                return -1;
04174             }
04175 
04176             /* This will only work for new messages... */
04177             header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
04178             /* empty string means no valid header */
04179             if (ast_strlen_zero(header_content)) {
04180                ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
04181                return -1;
04182             }
04183             /* Get header info needed by sendmail */
04184             temp = get_header_by_tag(header_content, "X-Asterisk-VM-Duration:");
04185             if (temp)
04186                duration = atoi(temp);
04187             else
04188                duration = 0;
04189 
04190             /* Attach only the first format */
04191             fmt = ast_strdupa(fmt);
04192             if (fmt) {
04193                stringp = fmt;
04194                strsep(&stringp, "|");
04195             } else {
04196                ast_log (LOG_ERROR,"audio format not set. Default to WAV\n");
04197                fmt = "WAV";
04198             }
04199             if (!strcasecmp(fmt, "wav49"))
04200                fmt = "WAV";
04201             if (option_debug > 2)
04202                ast_log (LOG_DEBUG,"**** format set to %s, vmfmts set to %s\n",fmt,vmfmts);
04203             /* ast_copy_string(fmt, vmfmts, sizeof(fmt));*/
04204             /* if (!ast_strlen_zero(fmt)) { */
04205             snprintf(todir, sizeof(todir), "%s%s/%s/tmp", VM_SPOOL_DIR, vmtmp->context, vmtmp->mailbox);
04206             make_gsm_file(vms->fn, sizeof(vms->fn), vms->imapuser, todir, vms->curmsg);
04207             if (option_debug > 2)
04208                ast_log (LOG_DEBUG,"Before mail_fetchstructure, message number is %ld, filename is:%s\n",vms->msgArray[vms->curmsg], vms->fn);
04209             /*mail_fetchstructure (mailstream, vmArray[0], &body); */
04210             mail_fetchstructure (vms->mailstream, vms->msgArray[vms->curmsg], &body);
04211             save_body(body,vms,"3","gsm");
04212             /* should not assume "fmt" here! */
04213             save_body(body,vms,"2",fmt);
04214 
04215             /* get destination mailbox */
04216             dstvms = get_vm_state_by_mailbox(vmtmp->mailbox,0);
04217             if (dstvms) {
04218                init_mailstream(dstvms, 0);
04219                if (!dstvms->mailstream) {
04220                   ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
04221                } else {
04222                   STORE(todir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
04223                   run_externnotify(vmtmp->context, vmtmp->mailbox); 
04224                }
04225             } else {
04226                ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
04227             }
04228 
04229             myserveremail = serveremail;
04230             if (!ast_strlen_zero(vmtmp->serveremail))
04231                myserveremail = vmtmp->serveremail;
04232             attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
04233             attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
04234             /* NULL category for IMAP storage */
04235             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);
04236 #else
04237             copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir);
04238 #endif
04239             saved_messages++;
04240             AST_LIST_REMOVE_CURRENT(&extensions, list);
04241             free_user(vmtmp);
04242             if (res)
04243                break;
04244          }
04245          AST_LIST_TRAVERSE_SAFE_END;
04246          if (saved_messages > 0) {
04247             /* give confirmation that the message was saved */
04248             /* commented out since we can't forward batches yet
04249             if (saved_messages == 1)
04250                res = ast_play_and_wait(chan, "vm-message");
04251             else
04252                res = ast_play_and_wait(chan, "vm-messages");
04253             if (!res)
04254                res = ast_play_and_wait(chan, "vm-saved"); */
04255             res = ast_play_and_wait(chan, "vm-msgsaved");
04256          }  
04257       }
04258 
04259       /* Remove surrogate file */
04260       vm_delete(msgfile);
04261    }
04262 
04263    /* If anything failed above, we still have this list to free */
04264    while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list)))
04265       free_user(vmtmp);
04266    return res ? res : cmd;
04267 }

static void free_user ( struct ast_vm_user vmu  )  [static]

Definition at line 2132 of file app_voicemail_odbc.c.

References ast_test_flag, free, and VM_ALLOCED.

02133 {
02134    if (ast_test_flag(vmu, VM_ALLOCED))
02135       free(vmu);
02136 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 2138 of file app_voicemail_odbc.c.

References free.

02139 {
02140    free(z);
02141 }

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

Definition at line 2065 of file app_voicemail_odbc.c.

References ast_localtime(), and t.

02066 {
02067    struct tm tm;
02068    time_t t;
02069 
02070    time(&t);
02071 
02072    ast_localtime(&t, &tm, NULL);
02073 
02074    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
02075 }

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

Definition at line 3792 of file app_voicemail_odbc.c.

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

03793 {
03794    int x;
03795    int d;
03796    char fn[PATH_MAX];
03797    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
03798    if (d)
03799       return d;
03800    for (x = start; x< 5; x++) {  /* For all folders */
03801       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
03802          return d;
03803       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
03804       if (d)
03805          return d;
03806       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
03807       d = vm_play_folder_name(chan, fn);
03808       if (d)
03809          return d;
03810       d = ast_waitfordigit(chan, 500);
03811       if (d)
03812          return d;
03813    }
03814    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
03815    if (d)
03816       return d;
03817    d = ast_waitfordigit(chan, 4000);
03818    return d;
03819 }

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

Definition at line 3821 of file app_voicemail_odbc.c.

References ast_play_and_wait(), and get_folder().

03822 {
03823    int res = 0;
03824    res = ast_play_and_wait(chan, fn);  /* Folder name */
03825    while (((res < '0') || (res > '9')) &&
03826          (res != '#') && (res >= 0)) {
03827       res = get_folder(chan, 0);
03828    }
03829    return res;
03830 }

static int get_lastdigits ( int  num  )  [static]

Definition at line 5703 of file app_voicemail_odbc.c.

05704 {
05705    num %= 100;
05706    return (num < 20) ? num : num % 10;
05707 }

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

Definition at line 7252 of file app_voicemail_odbc.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.

07253 {
07254    struct ast_vm_user *vmu;
07255    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
07256 
07257    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
07258    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
07259 
07260    AST_LIST_LOCK(&users);
07261    if (!AST_LIST_EMPTY(&users)) {
07262       if (argc == 3)
07263          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
07264       else {
07265          int count = 0;
07266          AST_LIST_TRAVERSE(&users, vmu, list) {
07267             if (!strcmp(argv[4],vmu->context))
07268                count++;
07269          }
07270          if (count) {
07271             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
07272          } else {
07273             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
07274             AST_LIST_UNLOCK(&users);
07275             return RESULT_FAILURE;
07276          }
07277       }
07278       AST_LIST_TRAVERSE(&users, vmu, list) {
07279          int newmsgs = 0, oldmsgs = 0;
07280          char count[12], tmp[256] = "";
07281 
07282          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
07283             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
07284             inboxcount(tmp, &newmsgs, &oldmsgs);
07285             snprintf(count,sizeof(count),"%d",newmsgs);
07286             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
07287          }
07288       }
07289    } else {
07290       ast_cli(fd, "There are no voicemail users currently defined\n");
07291       AST_LIST_UNLOCK(&users);
07292       return RESULT_FAILURE;
07293    }
07294    AST_LIST_UNLOCK(&users);
07295    return RESULT_SUCCESS;
07296 }

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

Definition at line 7298 of file app_voicemail_odbc.c.

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

07299 {
07300    struct vm_zone *zone;
07301    char *output_format = "%-15s %-20s %-45s\n";
07302    int res = RESULT_SUCCESS;
07303 
07304    if (argc != 3)
07305       return RESULT_SHOWUSAGE;
07306 
07307    AST_LIST_LOCK(&zones);
07308    if (!AST_LIST_EMPTY(&zones)) {
07309       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
07310       AST_LIST_TRAVERSE(&zones, zone, list) {
07311          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
07312       }
07313    } else {
07314       ast_cli(fd, "There are no voicemail zones currently defined\n");
07315       res = RESULT_FAILURE;
07316    }
07317    AST_LIST_UNLOCK(&zones);
07318 
07319    return res;
07320 }

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

Definition at line 2702 of file app_voicemail_odbc.c.

References __has_voicemail(), and strsep().

02703 {
02704    char tmp[256], *tmp2 = tmp, *mbox, *context;
02705    ast_copy_string(tmp, mailbox, sizeof(tmp));
02706    while ((mbox = strsep(&tmp2, ","))) {
02707       if ((context = strchr(mbox, '@')))
02708          *context++ = '\0';
02709       else
02710          context = "default";
02711       if (__has_voicemail(context, mbox, folder, 1))
02712          return 1;
02713    }
02714    return 0;
02715 }

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

Definition at line 2718 of file app_voicemail_odbc.c.

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

02719 {
02720    char tmp[256];
02721    char *context;
02722 
02723    if (newmsgs)
02724       *newmsgs = 0;
02725    if (oldmsgs)
02726       *oldmsgs = 0;
02727    /* If no mailbox, return immediately */
02728    if (ast_strlen_zero(mailbox))
02729       return 0;
02730    if (strchr(mailbox, ',')) {
02731       int tmpnew, tmpold;
02732       char *mb, *cur;
02733 
02734       ast_copy_string(tmp, mailbox, sizeof(tmp));
02735       mb = tmp;
02736       while ((cur = strsep(&mb, ", "))) {
02737          if (!ast_strlen_zero(cur)) {
02738             if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
02739                return -1;
02740             else {
02741                if (newmsgs)
02742                   *newmsgs += tmpnew; 
02743                if (oldmsgs)
02744                   *oldmsgs += tmpold;
02745             }
02746          }
02747       }
02748       return 0;
02749    }
02750    ast_copy_string(tmp, mailbox, sizeof(tmp));
02751    context = strchr(tmp, '@');
02752    if (context) {
02753       *context = '\0';
02754       context++;
02755    } else
02756       context = "default";
02757    if (newmsgs)
02758       *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
02759    if (oldmsgs)
02760       *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
02761    return 0;
02762 }

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

Definition at line 1593 of file app_voicemail_odbc.c.

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

01594 {
01595    int l;
01596 
01597    if (bio->ateof)
01598       return 0;
01599 
01600    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
01601       if (ferror(fi))
01602          return -1;
01603 
01604       bio->ateof = 1;
01605       return 0;
01606    }
01607 
01608    bio->iolen= l;
01609    bio->iocp= 0;
01610 
01611    return 1;
01612 }

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

Definition at line 1614 of file app_voicemail_odbc.c.

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

01615 {
01616    if (bio->iocp>=bio->iolen) {
01617       if (!inbuf(bio, fi))
01618          return EOF;
01619    }
01620 
01621    return bio->iobuf[bio->iocp++];
01622 }

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

Definition at line 2103 of file app_voicemail_odbc.c.

References ast_log(), ast_say_digit_str(), ast_stream_and_wait(), ast_vm_user::context, create_dirpath(), LOG_WARNING, and play_greeting().

02104 {
02105    int res;
02106    char fn[PATH_MAX];
02107    char dest[PATH_MAX];
02108 
02109    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, ext);
02110 
02111    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "greet"))) {
02112       ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
02113       return -1;
02114    }
02115 
02116    res = play_greeting(chan, vmu, fn, ecodes);
02117    if (res == -2) {
02118       /* File did not exist */
02119       res = ast_stream_and_wait(chan, "vm-theperson", chan->language, ecodes);
02120       if (res)
02121          return res;
02122       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
02123    }
02124 
02125    if (res)
02126       return res;
02127 
02128    res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language, ecodes);
02129    return res;
02130 }

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

Definition at line 1499 of file app_voicemail_odbc.c.

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

01500 {
01501    int x;
01502    char fn[PATH_MAX];
01503 
01504    if (vm_lock_path(dir))
01505       return ERROR_LOCK_PATH;
01506 
01507    for (x = 0; x < vmu->maxmsg; x++) {
01508       make_file(fn, sizeof(fn), dir, x);
01509       if (ast_fileexists(fn, NULL, NULL) < 1)
01510          break;
01511    }
01512    ast_unlock_path(dir);
01513 
01514    return x - 1;
01515 }

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

Definition at line 2813 of file app_voicemail_odbc.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, 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_greeting(), 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, and VOICEMAIL_FILE_MODE.

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

static int load_config ( void   )  [static]

Definition at line 7366 of file app_voicemail_odbc.c.

References 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, ast_vm_user::context, find_or_create(), free, free_user(), free_zone(), ast_variable::lineno, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, ast_variable::name, ast_variable::next, option_debug, populate_defaults(), s, SENDMAIL, strsep(), users, 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, and VOICEMAIL_CONFIG.

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

static int load_module ( void   )  [static]

Definition at line 7931 of file app_voicemail_odbc.c.

References ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_free, ast_install_vm_functions(), ast_log(), ast_module_helper(), AST_MODULE_LOAD_DECLINE, ast_register_application(), free, has_voicemail(), inboxcount(), load_config(), LOG_ERROR, messagecount(), vm_box_exists(), vm_exec(), vm_execmain(), and vmauthenticate().

07932 {
07933    int res;
07934    char *adsi_loaded = ast_module_helper("", "res_adsi.so", 0, 0, 0, 0);
07935    free(adsi_loaded);
07936    if (!adsi_loaded) {
07937       /* If embedded, res_adsi may be known as "res_adsi" not "res_adsi.so" */
07938       adsi_loaded = ast_module_helper("", "res_adsi", 0, 0, 0, 0);
07939       ast_free(adsi_loaded);
07940       if (!adsi_loaded) {
07941          ast_log(LOG_ERROR, "app_voicemail.so depends upon res_adsi.so\n");
07942          return AST_MODULE_LOAD_DECLINE;
07943       }
07944    }
07945 
07946    my_umask = umask(0);
07947    umask(my_umask);
07948    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
07949    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
07950    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
07951    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
07952    if (res)
07953       return(res);
07954 
07955    if ((res=load_config())) {
07956       return(res);
07957    }
07958 
07959    ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
07960 
07961    /* compute the location of the voicemail spool directory */
07962    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
07963 
07964    ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
07965 
07966    return res;
07967 }

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

Definition at line 879 of file app_voicemail_odbc.c.

00880 {
00881    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
00882 }

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 1785 of file app_voicemail_odbc.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(), ast_vm_user::context, create_dirpath(), ast_vm_user::email, ENDL, ast_vm_user::fullname, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, 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.

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

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

Definition at line 915 of file app_voicemail_odbc.c.

00916 {
00917    return snprintf(dest, len, "%s/msg%04d", dir, num);
00918 }

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

Definition at line 2143 of file app_voicemail_odbc.c.

02144 {
02145    static const char *msgs[] = {
02146       "INBOX",
02147       "Old",
02148       "Work",
02149       "Family",
02150       "Friends",
02151       "Cust1",
02152       "Cust2",
02153       "Cust3",
02154       "Cust4",
02155       "Cust5",
02156    };
02157    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "tmp";
02158 }

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

Definition at line 2665 of file app_voicemail_odbc.c.

References __has_voicemail().

02666 {
02667    return __has_voicemail(context, mailbox, folder, 0);
02668 }

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 3935 of file app_voicemail_odbc.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, 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.

03936 {
03937    char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
03938    int newmsgs = 0, oldmsgs = 0;
03939    const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
03940 
03941    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
03942    make_file(fn, sizeof(fn), todir, msgnum);
03943    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
03944 
03945    if (!ast_strlen_zero(vmu->attachfmt)) {
03946       if (strstr(fmt, vmu->attachfmt)) {
03947          fmt = vmu->attachfmt;
03948       } else {
03949          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);
03950       }
03951    }
03952 
03953    /* Attach only the first format */
03954    fmt = ast_strdupa(fmt);
03955    stringp = fmt;
03956    strsep(&stringp, "|");
03957 
03958    if (!ast_strlen_zero(vmu->email)) {
03959       int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
03960       char *myserveremail = serveremail;
03961       attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
03962       if (!ast_strlen_zero(vmu->serveremail))
03963          myserveremail = vmu->serveremail;
03964       
03965       if (attach_user_voicemail)
03966          RETRIEVE(todir, msgnum);
03967 
03968       /*XXX possible imap issue, should category be NULL XXX*/
03969       sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
03970 
03971       if (attach_user_voicemail)
03972          DISPOSE(todir, msgnum);
03973    }
03974 
03975    if (!ast_strlen_zero(vmu->pager)) {
03976       char *myserveremail = serveremail;
03977       if (!ast_strlen_zero(vmu->serveremail))
03978          myserveremail = vmu->serveremail;
03979       sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu, category);
03980    }
03981 
03982    if (ast_test_flag(vmu, VM_DELETE)) {
03983       DELETE(todir, msgnum, fn);
03984    }
03985 
03986 #ifdef IMAP_STORAGE
03987    DELETE(todir, msgnum, fn);
03988 #endif
03989    /* Leave voicemail for someone */
03990    if (ast_app_has_voicemail(ext_context, NULL)) {
03991       ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
03992    }
03993    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);
03994    run_externnotify(vmu->context, vmu->mailbox);
03995    return 0;
03996 }

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

Definition at line 1624 of file app_voicemail_odbc.c.

References BASELINELEN, eol, and baseio::linelength.

01625 {
01626    if (bio->linelength>=BASELINELEN) {
01627       if (fputs(eol,so)==EOF)
01628          return -1;
01629 
01630       bio->linelength= 0;
01631    }
01632 
01633    if (putc(((unsigned char)c),so)==EOF)
01634       return -1;
01635 
01636    bio->linelength++;
01637 
01638    return 1;
01639 }

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

Definition at line 4864 of file app_voicemail_odbc.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.

04865 {
04866    int res = 0;
04867    int count_msg, last_msg;
04868 
04869    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
04870    
04871    /* Rename the member vmbox HERE so that we don't try to return before
04872     * we know what's going on.
04873     */
04874    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
04875    
04876    /* Faster to make the directory than to check if it exists. */
04877    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
04878 
04879    count_msg = count_messages(vmu, vms->curdir);
04880    if (count_msg < 0)
04881       return count_msg;
04882    else
04883       vms->lastmsg = count_msg - 1;
04884 
04885    /*
04886    The following test is needed in case sequencing gets messed up.
04887    There appears to be more than one way to mess up sequence, so
04888    we will not try to find all of the root causes--just fix it when
04889    detected.
04890    */
04891 
04892    last_msg = last_message_index(vmu, vms->curdir);
04893    if (last_msg < 0)
04894       return last_msg;
04895    else if (vms->lastmsg != last_msg)
04896    {
04897       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
04898       res = resequence_mailbox(vmu, vms->curdir);
04899       if (res)
04900          return res;
04901    }
04902 
04903    return 0;
04904 }

static int play_greeting ( struct ast_channel chan,
struct ast_vm_user vmu,
char *  filename,
char *  ecodes 
) [static]

Definition at line 2077 of file app_voicemail_odbc.c.

References ast_fileexists(), ast_log(), ast_streamfile(), ast_waitstream(), ast_vm_user::context, DISPOSE, LOG_DEBUG, ast_vm_user::mailbox, option_debug, and RETRIEVE.

02078 {
02079    int res = -2;
02080 
02081 #ifdef ODBC_STORAGE
02082    int success = 
02083 #endif
02084    RETRIEVE(filename, -1);
02085    if (ast_fileexists(filename, NULL, NULL) > 0) {
02086       res = ast_streamfile(chan, filename, chan->language);
02087       if (res > -1) 
02088          res = ast_waitstream(chan, ecodes);
02089 #ifdef ODBC_STORAGE
02090       if (success == -1) {
02091          /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
02092          if (option_debug)
02093             ast_log(LOG_DEBUG, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
02094          store_file(filename, vmu->mailbox, vmu->context, -1);
02095       }
02096 #endif
02097    }
02098    DISPOSE(filename, -1);
02099 
02100    return res;
02101 }

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

Definition at line 4619 of file app_voicemail_odbc.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().

04620 {
04621    int res = 0;
04622    char filename[256], *cid;
04623    const char *origtime, *context, *category, *duration;
04624    struct ast_config *msg_cfg;
04625 
04626    vms->starting = 0; 
04627    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
04628    adsi_message(chan, vms);
04629    if (!vms->curmsg)
04630       res = wait_file2(chan, vms, "vm-first");  /* "First" */
04631    else if (vms->curmsg == vms->lastmsg)
04632       res = wait_file2(chan, vms, "vm-last");      /* "last" */
04633    if (!res) {
04634       /* POLISH syntax */
04635       if (!strcasecmp(chan->language, "pl")) { 
04636          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
04637             int ten, one;
04638             char nextmsg[256];
04639             ten = (vms->curmsg + 1) / 10;
04640             one = (vms->curmsg + 1) % 10;
04641             
04642             if (vms->curmsg < 20) {
04643                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
04644                res = wait_file2(chan, vms, nextmsg);
04645             } else {
04646                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
04647                res = wait_file2(chan, vms, nextmsg);
04648                if (one > 0) {
04649                   if (!res) {
04650                      snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
04651                      res = wait_file2(chan, vms, nextmsg);
04652                   }
04653                }
04654             }
04655          }
04656          if (!res)
04657             res = wait_file2(chan, vms, "vm-message");
04658       } else {
04659          if (!strcasecmp(chan->language, "se")) /* SWEDISH syntax */
04660             res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
04661          else /* DEFAULT syntax */
04662             res = wait_file2(chan, vms, "vm-message");
04663          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
04664             if (!res)
04665                res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
04666          }
04667       }
04668    }
04669 
04670    /* Retrieve info from VM attribute file */
04671    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
04672    snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
04673    RETRIEVE(vms->curdir, vms->curmsg);
04674    msg_cfg = ast_config_load(filename);
04675    if (!msg_cfg) {
04676       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
04677       return 0;
04678    }
04679 
04680    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
04681       ast_log(LOG_WARNING, "No origtime?!\n");
04682       DISPOSE(vms->curdir, vms->curmsg);
04683       ast_config_destroy(msg_cfg);
04684       return 0;
04685    }
04686 
04687    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
04688    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
04689    category = ast_variable_retrieve(msg_cfg, "message", "category");
04690 
04691    context = ast_variable_retrieve(msg_cfg, "message", "context");
04692    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
04693       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
04694    if (!res)
04695       res = play_message_category(chan, category);
04696    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
04697       res = play_message_datetime(chan, vmu, origtime, filename);
04698    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
04699       res = play_message_callerid(chan, vms, cid, context, 0);
04700    if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
04701       res = play_message_duration(chan, vms, duration, vmu->saydurationm);
04702    /* Allow pressing '1' to skip envelope / callerid */
04703    if (res == '1')
04704       res = 0;
04705    ast_config_destroy(msg_cfg);
04706 
04707    if (!res) {
04708       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
04709       vms->heard[vms->curmsg] = 1;
04710       if ((res = wait_file(chan, vms, vms->fn)) < 0) {
04711          ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn);
04712          res = 0;
04713       }
04714    }
04715    DISPOSE(vms->curdir, vms->curmsg);
04716    return res;
04717 }

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

Definition at line 4367 of file app_voicemail_odbc.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(), LOG_DEBUG, MAX_NUM_CID_CONTEXTS, name, option_debug, option_verbose, VERBOSE_PREFIX_3, and wait_file2().

04368 {
04369    int res = 0;
04370    int i;
04371    char *callerid, *name;
04372    char prefile[PATH_MAX] = "";
04373    
04374 
04375    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
04376    /* 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 */
04377    if ((cid == NULL)||(context == NULL))
04378       return res;
04379 
04380    /* Strip off caller ID number from name */
04381    if (option_debug > 2)
04382       ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
04383    ast_callerid_parse(cid, &name, &callerid);
04384    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
04385       /* Check for internal contexts and only */
04386       /* say extension when the call didn't come from an internal context in the list */
04387       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
04388          if (option_debug > 2)
04389             ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
04390          if ((strcmp(cidinternalcontexts[i], context) == 0))
04391             break;
04392       }
04393       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
04394          if (!res) {
04395             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
04396             if (!ast_strlen_zero(prefile)) {
04397             /* See if we can find a recorded name for this person instead of their extension number */
04398                if (ast_fileexists(prefile, NULL, NULL) > 0) {
04399                   if (option_verbose > 2)
04400                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
04401                   if (!callback)
04402                      res = wait_file2(chan, vms, "vm-from");
04403                   res = ast_stream_and_wait(chan, prefile, chan->language, "");
04404                } else {
04405                   if (option_verbose > 2)
04406                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
04407                   /* BB: Say "from extension" as one saying to sound smoother */
04408                   if (!callback)
04409                      res = wait_file2(chan, vms, "vm-from-extension");
04410                   res = ast_say_digit_str(chan, callerid, "", chan->language);
04411                }
04412             }
04413          }
04414       }
04415 
04416       else if (!res){
04417          if (option_debug > 2)
04418             ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
04419          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
04420          if (!callback)
04421             res = wait_file2(chan, vms, "vm-from-phonenumber");
04422          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
04423       }
04424    } else {
04425       /* Number unknown */
04426       if (option_debug)
04427          ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
04428       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
04429       res = wait_file2(chan, vms, "vm-unknown-caller");
04430    }
04431    return res;
04432 }

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

Definition at line 4282 of file app_voicemail_odbc.c.

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

04283 {
04284    int res = 0;
04285 
04286    if (!ast_strlen_zero(category))
04287       res = ast_play_and_wait(chan, category);
04288 
04289    if (res) {
04290       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
04291       res = 0;
04292    }
04293 
04294    return res;
04295 }

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

Definition at line 4297 of file app_voicemail_odbc.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.

04298 {
04299    int res = 0;
04300    struct vm_zone *the_zone = NULL;
04301    time_t t;
04302 
04303    if (ast_get_time_t(origtime, &t, 0, NULL)) {
04304       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
04305       return 0;
04306    }
04307 
04308    /* Does this user have a timezone specified? */
04309    if (!ast_strlen_zero(vmu->zonetag)) {
04310       /* Find the zone in the list */
04311       struct vm_zone *z;
04312       AST_LIST_LOCK(&zones);
04313       AST_LIST_TRAVERSE(&zones, z, list) {
04314          if (!strcmp(z->name, vmu->zonetag)) {
04315             the_zone = z;
04316             break;
04317          }
04318       }
04319       AST_LIST_UNLOCK(&zones);
04320    }
04321 
04322 /* No internal variable parsing for now, so we'll comment it out for the time being */
04323 #if 0
04324    /* Set the DIFF_* variables */
04325    ast_localtime(&t, &time_now, NULL);
04326    tv_now = ast_tvnow();
04327    tnow = tv_now.tv_sec;
04328    ast_localtime(&tnow, &time_then, NULL);
04329 
04330    /* Day difference */
04331    if (time_now.tm_year == time_then.tm_year)
04332       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
04333    else
04334       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
04335    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
04336 
04337    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
04338 #endif
04339    if (the_zone)
04340       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
04341    else if (!strcasecmp(chan->language,"pl"))       /* POLISH syntax */
04342       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
04343    else if (!strcasecmp(chan->language,"se"))       /* SWEDISH syntax */
04344       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
04345    else if (!strcasecmp(chan->language,"no"))       /* NORWEGIAN syntax */
04346       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
04347    else if (!strcasecmp(chan->language,"de"))       /* GERMAN syntax */
04348       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
04349    else if (!strcasecmp(chan->language,"nl"))      /* DUTCH syntax */
04350       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
04351    else if (!strcasecmp(chan->language,"it"))      /* ITALIAN syntax */
04352       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);
04353    else if (!strcasecmp(chan->language,"gr"))
04354       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
04355    else if (!strcasecmp(chan->language,"pt_BR"))
04356       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);      
04357    else
04358       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
04359 #if 0
04360    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
04361 #endif
04362    return res;
04363 }

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

Definition at line 4434 of file app_voicemail_odbc.c.

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

04435 {
04436    int res = 0;
04437    int durationm;
04438    int durations;
04439    /* Verify that we have a duration for the message */
04440    if (duration == NULL)
04441       return res;
04442 
04443    /* Convert from seconds to minutes */
04444    durations=atoi(duration);
04445    durationm=(durations / 60);
04446 
04447    if (option_debug > 2)
04448       ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
04449 
04450    if ((!res) && (durationm >= minduration)) {
04451       res = wait_file2(chan, vms, "vm-duration");
04452 
04453       /* POLISH syntax */
04454       if (!strcasecmp(chan->language, "pl")) {
04455          div_t num = div(durationm, 10);
04456 
04457          if (durationm == 1) {
04458             res = ast_play_and_wait(chan, "digits/1z");
04459             res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
04460          } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
04461             if (num.rem == 2) {
04462                if (!num.quot) {
04463                   res = ast_play_and_wait(chan, "digits/2-ie");
04464                } else {
04465                   res = say_and_wait(chan, durationm - 2 , chan->language);
04466                   res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
04467                }
04468             } else {
04469                res = say_and_wait(chan, durationm, chan->language);
04470             }
04471             res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
04472          } else {
04473             res = say_and_wait(chan, durationm, chan->language);
04474             res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
04475          }
04476       /* DEFAULT syntax */
04477       } else {
04478          res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
04479          res = wait_file2(chan, vms, "vm-minutes");
04480       }
04481    }
04482    return res;
04483 }

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 8273 of file app_voicemail_odbc.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, option_verbose, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.

08276 {
08277    /* Record message & let caller review or re-record it, or set options if applicable */
08278    int res = 0;
08279    int cmd = 0;
08280    int max_attempts = 3;
08281    int attempts = 0;
08282    int recorded = 0;
08283    int message_exists = 0;
08284    signed char zero_gain = 0;
08285    char tempfile[PATH_MAX];
08286    char *acceptdtmf = "#";
08287    char *canceldtmf = "";
08288 
08289    /* Note that urgent and private are for flagging messages as such in the future */
08290 
08291    /* barf if no pointer passed to store duration in */
08292    if (duration == NULL) {
08293       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
08294       return -1;
08295    }
08296 
08297    if (!outsidecaller)
08298       snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
08299    else
08300       ast_copy_string(tempfile, recordfile, sizeof(tempfile));
08301 
08302    cmd = '3';  /* Want to start by recording */
08303 
08304    while ((cmd >= 0) && (cmd != 't')) {
08305       switch (cmd) {
08306       case '1':
08307          if (!message_exists) {
08308             /* In this case, 1 is to record a message */
08309             cmd = '3';
08310             break;
08311          } else {
08312             /* Otherwise 1 is to save the existing message */
08313             if (option_verbose > 2)
08314                ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
08315             if (!outsidecaller)
08316                ast_filerename(tempfile, recordfile, NULL);
08317             ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
08318             if (!outsidecaller) {
08319                STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
08320                DISPOSE(recordfile, -1);
08321             }
08322             cmd = 't';
08323             return res;
08324          }
08325       case '2':
08326          /* Review */
08327          if (option_verbose > 2)
08328             ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
08329          cmd = ast_stream_and_wait(chan, tempfile, chan->language, AST_DIGIT_ANY);
08330          break;
08331       case '3':
08332          message_exists = 0;
08333          /* Record */
08334          if (recorded == 1) {
08335             if (option_verbose > 2)
08336                ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
08337          } else { 
08338             if (option_verbose > 2)
08339                ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
08340          }
08341          if (recorded && outsidecaller) {
08342             cmd = ast_play_and_wait(chan, INTRO);
08343             cmd = ast_play_and_wait(chan, "beep");
08344          }
08345          recorded = 1;
08346          /* 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 */
08347          if (record_gain)
08348             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
08349          if (ast_test_flag(vmu, VM_OPERATOR))
08350             canceldtmf = "0";
08351          cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
08352          if (record_gain)
08353             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
08354          if (cmd == -1) {
08355             /* User has hung up, no options to give */
08356             if (!outsidecaller) {
08357                /* user was recording a greeting and they hung up, so let's delete the recording. */
08358                ast_filedelete(tempfile, NULL);
08359             }
08360             return cmd;
08361          }
08362          if (cmd == '0') {
08363             break;
08364          } else if (cmd == '*') {
08365             break;
08366          } 
08367 #if 0       
08368          else if (vmu->review && (*duration < 5)) {
08369             /* Message is too short */
08370             if (option_verbose > 2)
08371                ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
08372             cmd = ast_play_and_wait(chan, "vm-tooshort");
08373             cmd = ast_filedelete(tempfile, NULL);
08374             break;
08375          }
08376          else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
08377             /* Message is all silence */
08378             if (option_verbose > 2)
08379                ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
08380             cmd = ast_filedelete(tempfile, NULL);
08381             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
08382             if (!cmd)
08383                cmd = ast_play_and_wait(chan, "vm-speakup");
08384             break;
08385          }
08386 #endif
08387          else {
08388             /* If all is well, a message exists */
08389             message_exists = 1;
08390             cmd = 0;
08391          }
08392          break;
08393       case '4':
08394       case '5':
08395       case '6':
08396       case '7':
08397       case '8':
08398       case '9':
08399       case '*':
08400       case '#':
08401          cmd = ast_play_and_wait(chan, "vm-sorry");
08402          break;
08403 #if 0 
08404 /*  XXX Commented out for the moment because of the dangers of deleting
08405     a message while recording (can put the message numbers out of sync) */
08406       case '*':
08407          /* Cancel recording, delete message, offer to take another message*/
08408          cmd = ast_play_and_wait(chan, "vm-deleted");
08409          cmd = ast_filedelete(tempfile, NULL);
08410          if (outsidecaller) {
08411             res = vm_exec(chan, NULL);
08412             return res;
08413          }
08414          else
08415             return 1;
08416 #endif
08417       case '0':
08418          if (!ast_test_flag(vmu, VM_OPERATOR)) {
08419             cmd = ast_play_and_wait(chan, "vm-sorry");
08420             break;
08421          }
08422          if (message_exists || recorded) {
08423             cmd = ast_play_and_wait(chan, "vm-saveoper");
08424             if (!cmd)
08425                cmd = ast_waitfordigit(chan, 3000);
08426             if (cmd == '1') {
08427                ast_play_and_wait(chan, "vm-msgsaved");
08428                cmd = '0';
08429             } else {
08430                ast_play_and_wait(chan, "vm-deleted");
08431                DELETE(recordfile, -1, recordfile);
08432                cmd = '0';
08433             }
08434          }
08435          return cmd;
08436       default:
08437          /* If the caller is an ouside caller, and the review option is enabled,
08438             allow them to review the message, but let the owner of the box review
08439             their OGM's */
08440          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
08441             return cmd;
08442          if (message_exists) {
08443             cmd = ast_play_and_wait(chan, "vm-review");
08444          }
08445          else {
08446             cmd = ast_play_and_wait(chan, "vm-torerecord");
08447             if (!cmd)
08448                cmd = ast_waitfordigit(chan, 600);
08449          }
08450          
08451          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
08452             cmd = ast_play_and_wait(chan, "vm-reachoper");
08453             if (!cmd)
08454                cmd = ast_waitfordigit(chan, 600);
08455          }
08456 #if 0
08457          if (!cmd)
08458             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
08459 #endif
08460          if (!cmd)
08461             cmd = ast_waitfordigit(chan, 6000);
08462          if (!cmd) {
08463             attempts++;
08464          }
08465          if (attempts > max_attempts) {
08466             cmd = 't';
08467          }
08468       }
08469    }
08470    if (outsidecaller)
08471       ast_play_and_wait(chan, "vm-goodbye");
08472    if (cmd == 't')
08473       cmd = 0;
08474    return cmd;
08475 }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

Definition at line 575 of file app_voicemail_odbc.c.

References ast_copy_flags, AST_FLAGS_ALL, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::exit, ast_vm_user::maxmsg, ast_vm_user::saydurationm, and ast_vm_user::volgain.

00576 {
00577    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00578    if (saydurationminfo)
00579       vmu->saydurationm = saydurationminfo;
00580    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00581    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00582    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00583    if (maxmsg)
00584       vmu->maxmsg = maxmsg;
00585    vmu->volgain = volgain;
00586 }

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 1713 of file app_voicemail_odbc.c.

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

01714 {
01715    char callerid[256];
01716    /* Prepare variables for substition in email body and subject */
01717    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
01718    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
01719    snprintf(passdata, passdatasize, "%d", msgnum);
01720    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
01721    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
01722    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
01723    pbx_builtin_setvar_helper(ast, "VM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller"));
01724    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (cidname ? cidname : "an unknown caller"));
01725    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
01726    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
01727    pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
01728 }

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

Definition at line 1730 of file app_voicemail_odbc.c.

01731 {
01732    char *ptr = to;
01733    *ptr++ = '"';
01734    for (; ptr < to + len - 1; from++) {
01735       if (*from == '"')
01736          *ptr++ = '\\';
01737       else if (*from == '\0')
01738          break;
01739       *ptr++ = *from;
01740    }
01741    if (ptr < to + len - 1)
01742       *ptr++ = '"';
01743    *ptr = '\0';
01744    return to;
01745 }

static int reload ( void   )  [static]

Definition at line 7910 of file app_voicemail_odbc.c.

References load_config().

07911 {
07912    return(load_config());
07913 }

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

Definition at line 1484 of file app_voicemail_odbc.c.

References ast_filerename().

01485 {
01486    char stxt[PATH_MAX];
01487    char dtxt[PATH_MAX];
01488    ast_filerename(sfn,dfn,NULL);
01489    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
01490    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
01491    rename(stxt, dtxt);
01492 }

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

Definition at line 3213 of file app_voicemail_odbc.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().

03214 {
03215    /* we know max messages, so stop process when number is hit */
03216 
03217    int x,dest;
03218    char sfn[PATH_MAX];
03219    char dfn[PATH_MAX];
03220 
03221    if (vm_lock_path(dir))
03222       return ERROR_LOCK_PATH;
03223 
03224    for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
03225       make_file(sfn, sizeof(sfn), dir, x);
03226       if (EXISTS(dir, x, sfn, NULL)) {
03227          
03228          if (x != dest) {
03229             make_file(dfn, sizeof(dfn), dir, dest);
03230             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
03231          }
03232          
03233          dest++;
03234       }
03235    }
03236    ast_unlock_path(dir);
03237 
03238    return 0;
03239 }

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

Definition at line 774 of file app_voicemail_odbc.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.

00775 {
00776    /* This function could be made to generate one from a database, too */
00777    struct ast_vm_user *cur;
00778    int res = -1;
00779    AST_LIST_LOCK(&users);
00780    AST_LIST_TRAVERSE(&users, cur, list) {
00781       if ((!context || !strcasecmp(context, cur->context)) &&
00782          (!strcasecmp(mailbox, cur->mailbox)))
00783             break;
00784    }
00785    if (cur) {
00786       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00787       res = 0;
00788    }
00789    AST_LIST_UNLOCK(&users);
00790    return res;
00791 }

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

Definition at line 2766 of file app_voicemail_odbc.c.

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

02767 {
02768    char arguments[255];
02769    char ext_context[256] = "";
02770    int newvoicemails = 0, oldvoicemails = 0;
02771    struct ast_smdi_mwi_message *mwi_msg;
02772 
02773    if (!ast_strlen_zero(context))
02774       snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
02775    else
02776       ast_copy_string(ext_context, extension, sizeof(ext_context));
02777 
02778    if (!strcasecmp(externnotify, "smdi")) {
02779       if (ast_app_has_voicemail(ext_context, NULL)) 
02780          ast_smdi_mwi_set(smdi_iface, extension);
02781       else
02782          ast_smdi_mwi_unset(smdi_iface, extension);
02783 
02784       if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) {
02785          ast_log(LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension);
02786          if (!strncmp(mwi_msg->cause, "INV", 3))
02787             ast_log(LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
02788          else if (!strncmp(mwi_msg->cause, "BLK", 3))
02789             ast_log(LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
02790          ast_log(LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
02791          ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
02792       } else {
02793          if (option_debug)
02794             ast_log(LOG_DEBUG, "Successfully executed SMDI MWI change for %s\n", extension);
02795       }
02796    } else if (!ast_strlen_zero(externnotify)) {
02797       if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
02798          ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
02799       } else {
02800          snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
02801          if (option_debug)
02802             ast_log(LOG_DEBUG, "Executing %s\n", arguments);
02803          ast_safe_system(arguments);
02804       }
02805    }
02806 }

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

Definition at line 3249 of file app_voicemail_odbc.c.

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

03250 {
03251 #ifdef IMAP_STORAGE
03252    /* we must use mbox(x) folder names, and copy the message there */
03253    /* simple. huh? */
03254    long res;
03255    char sequence[10];
03256 
03257    /* if save to Old folder, just leave in INBOX */
03258    if (box == 1) return 10;
03259    /* get the real IMAP message number for this message */
03260    snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
03261    if (option_debug > 2)
03262       ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,(char *) mbox(box));
03263    res = mail_copy(vms->mailstream,sequence,(char *) mbox(box));
03264    if (res == 1) return 0;
03265    return 1;
03266 #else
03267    char *dir = vms->curdir;
03268    char *username = vms->username;
03269    char *context = vmu->context;
03270    char sfn[PATH_MAX];
03271    char dfn[PATH_MAX];
03272    char ddir[PATH_MAX];
03273    const char *dbox = mbox(box);
03274    int x;
03275    make_file(sfn, sizeof(sfn), dir, msg);
03276    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
03277 
03278    if (vm_lock_path(ddir))
03279       return ERROR_LOCK_PATH;
03280 
03281    for (x = 0; x < vmu->maxmsg; x++) {
03282       make_file(dfn, sizeof(dfn), ddir, x);
03283       if (!EXISTS(ddir, x, dfn, NULL))
03284          break;
03285    }
03286    if (x >= vmu->maxmsg) {
03287       ast_unlock_path(ddir);
03288       return ERROR_MAILBOX_FULL;
03289    }
03290    if (strcmp(sfn, dfn)) {
03291       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
03292    }
03293    ast_unlock_path(ddir);
03294 #endif
03295    return 0;
03296 }

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

Definition at line 3242 of file app_voicemail_odbc.c.

References AST_DIGIT_ANY, and ast_say_number().

03243 {
03244    int d;
03245    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
03246    return d;
03247 }

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 1951 of file app_voicemail_odbc.c.

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

01952 {
01953    FILE *p=NULL;
01954    char tmp[80] = "/tmp/astmail-XXXXXX";
01955    char tmp2[256];
01956 
01957    if (vmu && ast_strlen_zero(vmu->email)) {
01958       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
01959       return(0);
01960    }
01961    if (!strcmp(format, "wav49"))
01962       format = "WAV";
01963    if (option_debug > 2)
01964       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));
01965    /* Make a temporary file instead of piping directly to sendmail, in case the mail
01966       command hangs */
01967    if ((p = vm_mkftemp(tmp)) == NULL) {
01968       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
01969       return -1;
01970    } else {
01971       make_email_file(p, srcemail, vmu, msgnum, context, mailbox, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
01972       fclose(p);
01973       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
01974       ast_safe_system(tmp2);
01975       if (option_debug > 2)
01976          ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
01977    }
01978    return 0;
01979 }

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 1981 of file app_voicemail_odbc.c.

References ast_channel_alloc(), ast_channel_free(), ast_log(), ast_safe_system(), AST_STATE_DOWN, LOG_DEBUG, LOG_WARNING, option_debug, pbx_substitute_variables_helper(), prep_email_sub_vars(), vm_mkftemp(), and vmu_tm().

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

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 6347 of file app_voicemail_odbc.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.

06350 {
06351    int useadsi=0, valid=0, logretries=0;
06352    char password[AST_MAX_EXTENSION]="", *passptr;
06353    struct ast_vm_user vmus, *vmu = NULL;
06354 
06355    /* If ADSI is supported, setup login screen */
06356    adsi_begin(chan, &useadsi);
06357    if (!skipuser && useadsi)
06358       adsi_login(chan);
06359    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
06360       ast_log(LOG_WARNING, "Couldn't stream login file\n");
06361       return -1;
06362    }
06363    
06364    /* Authenticate them and get their mailbox/password */
06365    
06366    while (!valid && (logretries < maxlogins)) {
06367       /* Prompt for, and read in the username */
06368       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
06369          ast_log(LOG_WARNING, "Couldn't read username\n");
06370          return -1;
06371       }
06372       if (ast_strlen_zero(mailbox)) {
06373          if (chan->cid.cid_num) {
06374             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
06375          } else {
06376             if (option_verbose > 2)
06377                ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");  
06378             return -1;
06379          }
06380       }
06381       if (useadsi)
06382          adsi_password(chan);
06383 
06384       if (!ast_strlen_zero(prefix)) {
06385          char fullusername[80] = "";
06386          ast_copy_string(fullusername, prefix, sizeof(fullusername));
06387          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
06388          ast_copy_string(mailbox, fullusername, mailbox_size);
06389       }
06390 
06391       if (option_debug)
06392          ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
06393       vmu = find_user(&vmus, context, mailbox);
06394       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
06395          /* saved password is blank, so don't bother asking */
06396          password[0] = '\0';
06397       } else {
06398          if (ast_streamfile(chan, "vm-password", chan->language)) {
06399             ast_log(LOG_WARNING, "Unable to stream password file\n");
06400             return -1;
06401          }
06402          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
06403             ast_log(LOG_WARNING, "Unable to read password\n");
06404             return -1;
06405          }
06406       }
06407 
06408       if (vmu) {
06409          passptr = vmu->password;
06410          if (passptr[0] == '-') passptr++;
06411       }
06412       if (vmu && !strcmp(passptr, password))
06413          valid++;
06414       else {
06415          if (option_verbose > 2)
06416             ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
06417          if (!ast_strlen_zero(prefix))
06418             mailbox[0] = '\0';
06419       }
06420       logretries++;
06421       if (!valid) {
06422          if (skipuser || logretries >= maxlogins) {
06423             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
06424                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
06425                return -1;
06426             }
06427          } else {
06428             if (useadsi)
06429                adsi_login(chan);
06430             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
06431                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
06432                return -1;
06433             }
06434          }
06435          if (ast_waitstream(chan, "")) /* Channel is hung up */
06436             return -1;
06437       }
06438    }
06439    if (!valid && (logretries >= maxlogins)) {
06440       ast_stopstream(chan);
06441       ast_play_and_wait(chan, "vm-goodbye");
06442       return -1;
06443    }
06444    if (vmu && !skipuser) {
06445       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
06446    }
06447    return 0;
06448 }

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

Definition at line 7161 of file app_voicemail_odbc.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.

07162 {
07163    struct ast_module_user *u;
07164    struct ast_vm_user svm;
07165    char *context, *box;
07166    int priority_jump = 0;
07167    AST_DECLARE_APP_ARGS(args,
07168       AST_APP_ARG(mbox);
07169       AST_APP_ARG(options);
07170    );
07171 
07172    if (ast_strlen_zero(data)) {
07173       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
07174       return -1;
07175    }
07176 
07177    u = ast_module_user_add(chan);
07178 
07179    box = ast_strdupa(data);
07180 
07181    AST_STANDARD_APP_ARGS(args, box);
07182 
07183    if (args.options) {
07184       if (strchr(args.options, 'j'))
07185          priority_jump = 1;
07186    }
07187 
07188    if ((context = strchr(args.mbox, '@'))) {
07189       *context = '\0';
07190       context++;
07191    }
07192 
07193    if (find_user(&svm, context, args.mbox)) {
07194       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
07195       if (priority_jump || ast_opt_priority_jumping)
07196          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
07197             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);
07198    } else
07199       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
07200    ast_module_user_remove(u);
07201    return 0;
07202 }

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

Definition at line 6332 of file app_voicemail_odbc.c.

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

06333 {
06334    if (!strcasecmp(chan->language, "es")) {  /* SPANISH */
06335       return vm_browse_messages_es(chan, vms, vmu);
06336    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN */
06337       return vm_browse_messages_it(chan, vms, vmu);
06338    } else if (!strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) {   /* PORTUGUESE */
06339       return vm_browse_messages_pt(chan, vms, vmu);
06340    } else if (!strcasecmp(chan->language, "gr")){
06341       return vm_browse_messages_gr(chan, vms, vmu);   /* GREEK */
06342    } else { /* Default to English syntax */
06343       return vm_browse_messages_en(chan, vms, vmu);
06344    }
06345 }

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

Definition at line 6255 of file app_voicemail_odbc.c.

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

06256 {
06257    int cmd=0;
06258 
06259    if (vms->lastmsg > -1) {
06260       cmd = play_message(chan, vmu, vms);
06261    } else {
06262       cmd = ast_play_and_wait(chan, "vm-youhave");
06263       if (!cmd) 
06264          cmd = ast_play_and_wait(chan, "vm-no");
06265       if (!cmd) {
06266          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06267          cmd = ast_play_and_wait(chan, vms->fn);
06268       }
06269       if (!cmd)
06270          cmd = ast_play_and_wait(chan, "vm-messages");
06271    }
06272    return cmd;
06273 }

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

Definition at line 6295 of file app_voicemail_odbc.c.

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

06296 {
06297    int cmd=0;
06298 
06299    if (vms->lastmsg > -1) {
06300       cmd = play_message(chan, vmu, vms);
06301    } else {
06302       cmd = ast_play_and_wait(chan, "vm-youhaveno");
06303       if (!cmd)
06304          cmd = ast_play_and_wait(chan, "vm-messages");
06305       if (!cmd) {
06306          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06307          cmd = ast_play_and_wait(chan, vms->fn);
06308       }
06309    }
06310    return cmd;
06311 }

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

Definition at line 6227 of file app_voicemail_odbc.c.

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

06228 {
06229    int cmd=0;
06230 
06231    if (vms->lastmsg > -1) {
06232       cmd = play_message(chan, vmu, vms);
06233    } else {
06234       cmd = ast_play_and_wait(chan, "vm-youhaveno");
06235       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
06236          if (!cmd) {
06237             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
06238             cmd = ast_play_and_wait(chan, vms->fn);
06239          }
06240          if (!cmd)
06241             cmd = ast_play_and_wait(chan, "vm-messages");
06242       } else {
06243          if (!cmd)
06244             cmd = ast_play_and_wait(chan, "vm-messages");
06245          if (!cmd) {
06246             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06247             cmd = ast_play_and_wait(chan, vms->fn);
06248          }
06249       }
06250    } 
06251    return cmd;
06252 }

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

Definition at line 6276 of file app_voicemail_odbc.c.

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

06277 {
06278    int cmd=0;
06279 
06280    if (vms->lastmsg > -1) {
06281       cmd = play_message(chan, vmu, vms);
06282    } else {
06283       cmd = ast_play_and_wait(chan, "vm-no");
06284       if (!cmd)
06285          cmd = ast_play_and_wait(chan, "vm-message");
06286       if (!cmd) {
06287          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06288          cmd = ast_play_and_wait(chan, vms->fn);
06289       }
06290    }
06291    return cmd;
06292 }

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

Definition at line 6314 of file app_voicemail_odbc.c.

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

06315 {
06316    int cmd=0;
06317 
06318    if (vms->lastmsg > -1) {
06319       cmd = play_message(chan, vmu, vms);
06320    } else {
06321       cmd = ast_play_and_wait(chan, "vm-no");
06322       if (!cmd) {
06323          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06324          cmd = ast_play_and_wait(chan, vms->fn);
06325       }
06326       if (!cmd)
06327          cmd = ast_play_and_wait(chan, "vm-messages");
06328    }
06329    return cmd;
06330 }

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

Definition at line 793 of file app_voicemail_odbc.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.

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

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

Definition at line 868 of file app_voicemail_odbc.c.

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

00869 {
00870    char buf[255];
00871    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00872    if (!ast_safe_system(buf)) {
00873       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00874       /* Reset the password in memory, too */
00875       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00876    }
00877 }

static int vm_delete ( char *  file  )  [static]

Definition at line 1578 of file app_voicemail_odbc.c.

References ast_filedelete().

01579 {
01580    char *txt;
01581    int txtsize = 0;
01582 
01583    txtsize = (strlen(file) + 5)*sizeof(char);
01584    txt = alloca(txtsize);
01585    /* Sprintf here would safe because we alloca'd exactly the right length,
01586     * but trying to eliminate all sprintf's anyhow
01587     */
01588    snprintf(txt, txtsize, "%s.txt", file);
01589    unlink(txt);
01590    return ast_filedelete(file, NULL);
01591 }

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

Definition at line 7014 of file app_voicemail_odbc.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.

07015 {
07016    int res = 0;
07017    struct ast_module_user *u;
07018    char *tmp;
07019    struct leave_vm_options leave_options;
07020    struct ast_flags flags = { 0 };
07021    static int deprecate_warning = 0;
07022    char *opts[OPT_ARG_ARRAY_SIZE];
07023    AST_DECLARE_APP_ARGS(args,
07024       AST_APP_ARG(argv0);
07025       AST_APP_ARG(argv1);
07026    );
07027 
07028    u = ast_module_user_add(chan);
07029    
07030    memset(&leave_options, 0, sizeof(leave_options));
07031 
07032    if (chan->_state != AST_STATE_UP)
07033       ast_answer(chan);
07034 
07035    if (!ast_strlen_zero(data)) {
07036       tmp = ast_strdupa(data);
07037       AST_STANDARD_APP_ARGS(args, tmp);
07038       if (args.argc == 2) {
07039          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
07040             ast_module_user_remove(u);
07041             return -1;
07042          }
07043          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
07044          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07045             int gain;
07046 
07047             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
07048                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07049                ast_module_user_remove(u);
07050                return -1;
07051             } else {
07052                leave_options.record_gain = (signed char) gain;
07053             }
07054          }
07055       } else {
07056          /* old style options parsing */
07057          int old = 0;
07058          char *orig_argv0 = args.argv0;
07059          while (*(args.argv0)) {
07060             if (*(args.argv0) == 's') {
07061                old = 1;
07062                ast_set_flag(&leave_options, OPT_SILENT);
07063             } else if (*(args.argv0) == 'b') {
07064                old = 1;
07065                ast_set_flag(&leave_options, OPT_BUSY_GREETING);
07066             } else if (*(args.argv0) == 'u') {
07067                old = 1;
07068                ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
07069             } else if (*(args.argv0) == 'j') {
07070                old = 1;
07071                ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
07072             } else
07073                break;
07074             (args.argv0)++;
07075          }
07076          if (!deprecate_warning && old) {
07077             deprecate_warning = 1;
07078             ast_log(LOG_WARNING, "Prefixing the mailbox with an option is deprecated ('%s').\n", orig_argv0);
07079             ast_log(LOG_WARNING, "Please move all leading options to the second argument.\n");
07080          }
07081       }
07082    } else {
07083       char tmp[256];
07084       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
07085       if (res < 0) {
07086          ast_module_user_remove(u);
07087          return res;
07088       }
07089       if (ast_strlen_zero(tmp)) {
07090          ast_module_user_remove(u);
07091          return 0;
07092       }
07093       args.argv0 = ast_strdupa(tmp);
07094    }
07095 
07096    res = leave_voicemail(chan, args.argv0, &leave_options);
07097 
07098    if (res == ERROR_LOCK_PATH) {
07099       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
07100       /*Send the call to n+101 priority, where n is the current priority*/
07101       if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
07102          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
07103             ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
07104       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
07105       res = 0;
07106    }
07107    
07108    ast_module_user_remove(u);
07109 
07110    return res;
07111 }

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

Definition at line 6450 of file app_voicemail_odbc.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(), has_voicemail(), vm_state::heard, ast_vm_user::language, vm_state::lastmsg, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, make_file(), manager_event(), 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, and vm_state::vmbox.

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

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 3832 of file app_voicemail_odbc.c.

References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load(), ast_filecopy(), ast_filedelete(), 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(), and STORE.

03834 {
03835    int cmd = 0;
03836    int retries = 0, prepend_duration = 0, already_recorded = 0;
03837    signed char zero_gain = 0;
03838    struct ast_config *msg_cfg;
03839    const char *duration_str;
03840    char msgfile[PATH_MAX], backup[PATH_MAX];
03841    char textfile[PATH_MAX];
03842 
03843    /* Must always populate duration correctly */
03844    make_file(msgfile, sizeof(msgfile), curdir, curmsg);
03845    strcpy(textfile, msgfile);
03846    strcpy(backup, msgfile);
03847    strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
03848    strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
03849 
03850    if (!(msg_cfg = ast_config_load(textfile))) {
03851       return -1;
03852    }
03853 
03854    *duration = 0;
03855    if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
03856       *duration = atoi(duration_str);
03857 
03858    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
03859       if (cmd)
03860          retries = 0;
03861       switch (cmd) {
03862       case '1': 
03863          /* prepend a message to the current message, update the metadata and return */
03864       {
03865          prepend_duration = 0;
03866 
03867          /* if we can't read the message metadata, stop now */
03868          if (!msg_cfg) {
03869             cmd = 0;
03870             break;
03871          }
03872 
03873          /* Back up the original file, so we can retry the prepend */
03874          if (already_recorded)
03875             ast_filecopy(backup, msgfile, NULL);
03876          else
03877             ast_filecopy(msgfile, backup, NULL);
03878          already_recorded = 1;
03879 
03880          if (record_gain)
03881             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
03882 
03883          cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
03884          if (record_gain)
03885             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
03886 
03887          if (prepend_duration) {
03888             struct ast_category *msg_cat;
03889             /* need enough space for a maximum-length message duration */
03890             char duration_str[12];
03891 
03892             prepend_duration += *duration;
03893             msg_cat = ast_category_get(msg_cfg, "message");
03894             snprintf(duration_str, 11, "%d", prepend_duration);
03895             if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
03896                config_text_file_save(textfile, msg_cfg, "app_voicemail");
03897                STORE(curdir, vmu->mailbox, context, curmsg, chan, vmu, vmfmts, prepend_duration, vms);
03898             }
03899          }
03900 
03901          break;
03902       }
03903       case '2': 
03904          cmd = 't';
03905          break;
03906       case '*':
03907          cmd = '*';
03908          break;
03909       default: 
03910          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
03911             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
03912          if (!cmd)
03913             cmd = ast_play_and_wait(chan,"vm-starmain");
03914             /* "press star to return to the main menu" */
03915          if (!cmd)
03916             cmd = ast_waitfordigit(chan,6000);
03917          if (!cmd)
03918             retries++;
03919          if (retries > 3)
03920             cmd = 't';
03921       }
03922    }
03923 
03924    ast_config_destroy(msg_cfg);
03925    if (already_recorded)
03926       ast_filedelete(backup, NULL);
03927    if (prepend_duration)
03928       *duration = prepend_duration;
03929 
03930    if (cmd == 't' || cmd == 'S')
03931       cmd = 0;
03932    return cmd;
03933 }

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

Definition at line 5893 of file app_voicemail_odbc.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.

05894 {
05895    int res = 0;
05896    /* Play instructions and wait for new command */
05897    while (!res) {
05898       if (vms->starting) {
05899          if (vms->lastmsg > -1) {
05900             res = ast_play_and_wait(chan, "vm-onefor");
05901             if (!res)
05902                res = vm_play_folder_name(chan, vms->vmbox);
05903          }
05904          if (!res)
05905             res = ast_play_and_wait(chan, "vm-opts");
05906       } else {
05907          if (vms->curmsg)
05908             res = ast_play_and_wait(chan, "vm-prev");
05909          if (!res && !skipadvanced)
05910             res = ast_play_and_wait(chan, "vm-advopts");
05911          if (!res)
05912             res = ast_play_and_wait(chan, "vm-repeat");
05913          if (!res && (vms->curmsg != vms->lastmsg))
05914             res = ast_play_and_wait(chan, "vm-next");
05915          if (!res) {
05916             if (!vms->deleted[vms->curmsg])
05917                res = ast_play_and_wait(chan, "vm-delete");
05918             else
05919                res = ast_play_and_wait(chan, "vm-undelete");
05920             if (!res)
05921                res = ast_play_and_wait(chan, "vm-toforward");
05922             if (!res)
05923                res = ast_play_and_wait(chan, "vm-savemessage");
05924          }
05925       }
05926       if (!res)
05927          res = ast_play_and_wait(chan, "vm-helpexit");
05928       if (!res)
05929          res = ast_waitfordigit(chan, 6000);
05930       if (!res) {
05931          vms->repeats++;
05932          if (vms->repeats > 2) {
05933             res = 't';
05934          }
05935       }
05936    }
05937    return res;
05938 }

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

Definition at line 5848 of file app_voicemail_odbc.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(), and VM_TEMPGREETWARN.

05849 {
05850    char prefile[256];
05851    
05852    /* Notify the user that the temp greeting is set and give them the option to remove it */
05853    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
05854    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
05855       if (ast_fileexists(prefile, NULL, NULL) > 0)
05856          ast_play_and_wait(chan, "vm-tempgreetactive");
05857    }
05858 
05859    /* Play voicemail intro - syntax is different for different languages */
05860    if (!strcasecmp(chan->language, "de")) {  /* GERMAN syntax */
05861       return vm_intro_de(chan, vms);
05862    } else if (!strcasecmp(chan->language, "es")) { /* SPANISH syntax */
05863       return vm_intro_es(chan, vms);
05864    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN syntax */
05865       return vm_intro_it(chan, vms);
05866    } else if (!strcasecmp(chan->language, "fr")) { /* FRENCH syntax */
05867       return vm_intro_fr(chan, vms);
05868    } else if (!strcasecmp(chan->language, "nl")) { /* DUTCH syntax */
05869       return vm_intro_nl(chan, vms);
05870    } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE syntax */
05871       return vm_intro_pt(chan, vms);
05872    } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */
05873       return vm_intro_pt_BR(chan, vms);      
05874    } else if (!strcasecmp(chan->language, "cz")) { /* CZECH syntax */
05875       return vm_intro_cz(chan, vms);
05876    } else if (!strcasecmp(chan->language, "gr")) { /* GREEK syntax */
05877       return vm_intro_gr(chan, vms);
05878    } else if (!strcasecmp(chan->language, "pl")) { /* POLISH syntax */
05879       return vm_intro_pl(chan, vms);
05880    } else if (!strcasecmp(chan->language, "se")) { /* SWEDISH syntax */
05881       return vm_intro_se(chan, vms);
05882    } else if (!strcasecmp(chan->language, "no")) { /* NORWEGIAN syntax */
05883       return vm_intro_no(chan, vms);
05884    } else if (!strcasecmp(chan->language, "ru")) { /* RUSSIAN syntax */
05885       return vm_intro_ru(chan, vms);
05886    } else if (!strcasecmp(chan->language, "ua")) { /* UKRAINIAN syntax */
05887       return vm_intro_ua(chan, vms);
05888    } else {             /* Default to ENGLISH */
05889       return vm_intro_en(chan, vms);
05890    }
05891 }

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

Definition at line 5643 of file app_voicemail_odbc.c.

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

05644 {
05645    int res;
05646    res = ast_play_and_wait(chan, "vm-youhave");
05647    if (!res) {
05648       if (vms->newmessages) {
05649          if (vms->newmessages == 1) {
05650             res = ast_play_and_wait(chan, "digits/jednu");
05651          } else {
05652             res = say_and_wait(chan, vms->newmessages, chan->language);
05653          }
05654          if (!res) {
05655             if ((vms->newmessages == 1))
05656                res = ast_play_and_wait(chan, "vm-novou");
05657             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
05658                res = ast_play_and_wait(chan, "vm-nove");
05659             if (vms->newmessages > 4)
05660                res = ast_play_and_wait(chan, "vm-novych");
05661          }
05662          if (vms->oldmessages && !res)
05663             res = ast_play_and_wait(chan, "vm-and");
05664          else if (!res) {
05665             if ((vms->newmessages == 1))
05666                res = ast_play_and_wait(chan, "vm-zpravu");
05667             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
05668                res = ast_play_and_wait(chan, "vm-zpravy");
05669             if (vms->newmessages > 4)
05670                res = ast_play_and_wait(chan, "vm-zprav");
05671          }
05672       }
05673       if (!res && vms->oldmessages) {
05674          res = say_and_wait(chan, vms->oldmessages, chan->language);
05675          if (!res) {
05676             if ((vms->oldmessages == 1))
05677                res = ast_play_and_wait(chan, "vm-starou");
05678             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
05679                res = ast_play_and_wait(chan, "vm-stare");
05680             if (vms->oldmessages > 4)
05681                res = ast_play_and_wait(chan, "vm-starych");
05682          }
05683          if (!res) {
05684             if ((vms->oldmessages == 1))
05685                res = ast_play_and_wait(chan, "vm-zpravu");
05686             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
05687                res = ast_play_and_wait(chan, "vm-zpravy");
05688             if (vms->oldmessages > 4)
05689                res = ast_play_and_wait(chan, "vm-zprav");
05690          }
05691       }
05692       if (!res) {
05693          if (!vms->oldmessages && !vms->newmessages) {
05694             res = ast_play_and_wait(chan, "vm-no");
05695             if (!res)
05696                res = ast_play_and_wait(chan, "vm-zpravy");
05697          }
05698       }
05699    }
05700    return res;
05701 }

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

Definition at line 5336 of file app_voicemail_odbc.c.

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

05337 {
05338    /* Introduce messages they have */
05339    int res;
05340    res = ast_play_and_wait(chan, "vm-youhave");
05341    if (!res) {
05342       if (vms->newmessages) {
05343          if ((vms->newmessages == 1))
05344             res = ast_play_and_wait(chan, "digits/1F");
05345          else
05346             res = say_and_wait(chan, vms->newmessages, chan->language);
05347          if (!res)
05348             res = ast_play_and_wait(chan, "vm-INBOX");
05349          if (vms->oldmessages && !res)
05350             res = ast_play_and_wait(chan, "vm-and");
05351          else if (!res) {
05352             if ((vms->newmessages == 1))
05353                res = ast_play_and_wait(chan, "vm-message");
05354             else
05355                res = ast_play_and_wait(chan, "vm-messages");
05356          }
05357             
05358       }
05359       if (!res && vms->oldmessages) {
05360          if (vms->oldmessages == 1)
05361             res = ast_play_and_wait(chan, "digits/1F");
05362          else
05363             res = say_and_wait(chan, vms->oldmessages, chan->language);
05364          if (!res)
05365             res = ast_play_and_wait(chan, "vm-Old");
05366          if (!res) {
05367             if (vms->oldmessages == 1)
05368                res = ast_play_and_wait(chan, "vm-message");
05369             else
05370                res = ast_play_and_wait(chan, "vm-messages");
05371          }
05372       }
05373       if (!res) {
05374          if (!vms->oldmessages && !vms->newmessages) {
05375             res = ast_play_and_wait(chan, "vm-no");
05376             if (!res)
05377                res = ast_play_and_wait(chan, "vm-messages");
05378          }
05379       }
05380    }
05381    return res;
05382 }

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

Definition at line 5098 of file app_voicemail_odbc.c.

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

05099 {
05100    int res;
05101 
05102    /* Introduce messages they have */
05103    res = ast_play_and_wait(chan, "vm-youhave");
05104    if (!res) {
05105       if (vms->newmessages) {
05106          res = say_and_wait(chan, vms->newmessages, chan->language);
05107          if (!res)
05108             res = ast_play_and_wait(chan, "vm-INBOX");
05109          if (vms->oldmessages && !res)
05110             res = ast_play_and_wait(chan, "vm-and");
05111          else if (!res) {
05112             if ((vms->newmessages == 1))
05113                res = ast_play_and_wait(chan, "vm-message");
05114             else
05115                res = ast_play_and_wait(chan, "vm-messages");
05116          }
05117             
05118       }
05119       if (!res && vms->oldmessages) {
05120          res = say_and_wait(chan, vms->oldmessages, chan->language);
05121          if (!res)
05122             res = ast_play_and_wait(chan, "vm-Old");
05123          if (!res) {
05124             if (vms->oldmessages == 1)
05125                res = ast_play_and_wait(chan, "vm-message");
05126             else
05127                res = ast_play_and_wait(chan, "vm-messages");
05128          }
05129       }
05130       if (!res) {
05131          if (!vms->oldmessages && !vms->newmessages) {
05132             res = ast_play_and_wait(chan, "vm-no");
05133             if (!res)
05134                res = ast_play_and_wait(chan, "vm-messages");
05135          }
05136       }
05137    }
05138    return res;
05139 }

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

Definition at line 5385 of file app_voicemail_odbc.c.

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

05386 {
05387    /* Introduce messages they have */
05388    int res;
05389    if (!vms->oldmessages && !vms->newmessages) {
05390       res = ast_play_and_wait(chan, "vm-youhaveno");
05391       if (!res)
05392          res = ast_play_and_wait(chan, "vm-messages");
05393    } else {
05394       res = ast_play_and_wait(chan, "vm-youhave");
05395    }
05396    if (!res) {
05397       if (vms->newmessages) {
05398          if (!res) {
05399             if ((vms->newmessages == 1)) {
05400                res = ast_play_and_wait(chan, "digits/1M");
05401                if (!res)
05402                   res = ast_play_and_wait(chan, "vm-message");
05403                if (!res)
05404                   res = ast_play_and_wait(chan, "vm-INBOXs");
05405             } else {
05406                res = say_and_wait(chan, vms->newmessages, chan->language);
05407                if (!res)
05408                   res = ast_play_and_wait(chan, "vm-messages");
05409                if (!res)
05410                   res = ast_play_and_wait(chan, "vm-INBOX");
05411             }
05412          }
05413          if (vms->oldmessages && !res)
05414             res = ast_play_and_wait(chan, "vm-and");
05415       }
05416       if (vms->oldmessages) {
05417          if (!res) {
05418             if (vms->oldmessages == 1) {
05419                res = ast_play_and_wait(chan, "digits/1M");
05420                if (!res)
05421                   res = ast_play_and_wait(chan, "vm-message");
05422                if (!res)
05423                   res = ast_play_and_wait(chan, "vm-Olds");
05424             } else {
05425                res = say_and_wait(chan, vms->oldmessages, chan->language);
05426                if (!res)
05427                   res = ast_play_and_wait(chan, "vm-messages");
05428                if (!res)
05429                   res = ast_play_and_wait(chan, "vm-Old");
05430             }
05431          }
05432       }
05433    }
05434 return res;
05435 }

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

Definition at line 5486 of file app_voicemail_odbc.c.

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

05487 {
05488    /* Introduce messages they have */
05489    int res;
05490    res = ast_play_and_wait(chan, "vm-youhave");
05491    if (!res) {
05492       if (vms->newmessages) {
05493          res = say_and_wait(chan, vms->newmessages, chan->language);
05494          if (!res)
05495             res = ast_play_and_wait(chan, "vm-INBOX");
05496          if (vms->oldmessages && !res)
05497             res = ast_play_and_wait(chan, "vm-and");
05498          else if (!res) {
05499             if ((vms->newmessages == 1))
05500                res = ast_play_and_wait(chan, "vm-message");
05501             else
05502                res = ast_play_and_wait(chan, "vm-messages");
05503          }
05504             
05505       }
05506       if (!res && vms->oldmessages) {
05507          res = say_and_wait(chan, vms->oldmessages, chan->language);
05508          if (!res)
05509             res = ast_play_and_wait(chan, "vm-Old");
05510          if (!res) {
05511             if (vms->oldmessages == 1)
05512                res = ast_play_and_wait(chan, "vm-message");
05513             else
05514                res = ast_play_and_wait(chan, "vm-messages");
05515          }
05516       }
05517       if (!res) {
05518          if (!vms->oldmessages && !vms->newmessages) {
05519             res = ast_play_and_wait(chan, "vm-no");
05520             if (!res)
05521                res = ast_play_and_wait(chan, "vm-messages");
05522          }
05523       }
05524    }
05525    return res;
05526 }

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

Definition at line 5060 of file app_voicemail_odbc.c.

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

05061 {
05062    int res = 0;
05063 
05064    if (vms->newmessages) {
05065       res = ast_play_and_wait(chan, "vm-youhave");
05066       if (!res) 
05067          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
05068       if (!res) {
05069          if ((vms->newmessages == 1)) {
05070             res = ast_play_and_wait(chan, "vm-INBOX");
05071             if (!res)
05072                res = ast_play_and_wait(chan, "vm-message");
05073          } else {
05074             res = ast_play_and_wait(chan, "vm-INBOXs");
05075             if (!res)
05076                res = ast_play_and_wait(chan, "vm-messages");
05077          }
05078       }
05079    } else if (vms->oldmessages){
05080       res = ast_play_and_wait(chan, "vm-youhave");
05081       if (!res)
05082          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
05083       if ((vms->oldmessages == 1)){
05084          res = ast_play_and_wait(chan, "vm-Old");
05085          if (!res)
05086             res = ast_play_and_wait(chan, "vm-message");
05087       } else {
05088          res = ast_play_and_wait(chan, "vm-Olds");
05089          if (!res)
05090             res = ast_play_and_wait(chan, "vm-messages");
05091       }
05092    } else if (!vms->oldmessages && !vms->newmessages) 
05093       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
05094    return res;
05095 }

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

Definition at line 5142 of file app_voicemail_odbc.c.

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

05143 {
05144    /* Introduce messages they have */
05145    int res;
05146    if (!vms->oldmessages && !vms->newmessages)
05147       res = ast_play_and_wait(chan, "vm-no") ||
05148          ast_play_and_wait(chan, "vm-message");
05149    else
05150       res = ast_play_and_wait(chan, "vm-youhave");
05151    if (!res && vms->newmessages) {
05152       res = (vms->newmessages == 1) ?
05153          ast_play_and_wait(chan, "digits/un") ||
05154          ast_play_and_wait(chan, "vm-nuovo") ||
05155          ast_play_and_wait(chan, "vm-message") :
05156          /* 2 or more new messages */
05157          say_and_wait(chan, vms->newmessages, chan->language) ||
05158          ast_play_and_wait(chan, "vm-nuovi") ||
05159          ast_play_and_wait(chan, "vm-messages");
05160       if (!res && vms->oldmessages)
05161          res = ast_play_and_wait(chan, "vm-and");
05162    }
05163    if (!res && vms->oldmessages) {
05164       res = (vms->oldmessages == 1) ?
05165          ast_play_and_wait(chan, "digits/un") ||
05166          ast_play_and_wait(chan, "vm-vecchio") ||
05167          ast_play_and_wait(chan, "vm-message") :
05168          /* 2 or more old messages */
05169          say_and_wait(chan, vms->oldmessages, chan->language) ||
05170          ast_play_and_wait(chan, "vm-vecchi") ||
05171          ast_play_and_wait(chan, "vm-messages");
05172    }
05173    return res ? -1 : 0;
05174 }

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

Definition at line 5529 of file app_voicemail_odbc.c.

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

05530 {
05531    /* Introduce messages they have */
05532    int res;
05533    res = ast_play_and_wait(chan, "vm-youhave");
05534    if (!res) {
05535       if (vms->newmessages) {
05536          res = say_and_wait(chan, vms->newmessages, chan->language);
05537          if (!res) {
05538             if (vms->newmessages == 1)
05539                res = ast_play_and_wait(chan, "vm-INBOXs");
05540             else
05541                res = ast_play_and_wait(chan, "vm-INBOX");
05542          }
05543          if (vms->oldmessages && !res)
05544             res = ast_play_and_wait(chan, "vm-and");
05545          else if (!res) {
05546             if ((vms->newmessages == 1))
05547                res = ast_play_and_wait(chan, "vm-message");
05548             else
05549                res = ast_play_and_wait(chan, "vm-messages");
05550          }
05551             
05552       }
05553       if (!res && vms->oldmessages) {
05554          res = say_and_wait(chan, vms->oldmessages, chan->language);
05555          if (!res) {
05556             if (vms->oldmessages == 1)
05557                res = ast_play_and_wait(chan, "vm-Olds");
05558             else
05559                res = ast_play_and_wait(chan, "vm-Old");
05560          }
05561          if (!res) {
05562             if (vms->oldmessages == 1)
05563                res = ast_play_and_wait(chan, "vm-message");
05564             else
05565                res = ast_play_and_wait(chan, "vm-messages");
05566          }
05567       }
05568       if (!res) {
05569          if (!vms->oldmessages && !vms->newmessages) {
05570             res = ast_play_and_wait(chan, "vm-no");
05571             if (!res)
05572                res = ast_play_and_wait(chan, "vm-messages");
05573          }
05574       }
05575    }
05576    return res;
05577 }

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

Definition at line 5292 of file app_voicemail_odbc.c.

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

05293 {
05294    /* Introduce messages they have */
05295    int res;
05296 
05297    res = ast_play_and_wait(chan, "vm-youhave");
05298    if (res)
05299       return res;
05300 
05301    if (!vms->oldmessages && !vms->newmessages) {
05302       res = ast_play_and_wait(chan, "vm-no");
05303       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05304       return res;
05305    }
05306 
05307    if (vms->newmessages) {
05308       if ((vms->newmessages == 1)) {
05309          res = ast_play_and_wait(chan, "digits/1");
05310          res = res ? res : ast_play_and_wait(chan, "vm-ny");
05311          res = res ? res : ast_play_and_wait(chan, "vm-message");
05312       } else {
05313          res = say_and_wait(chan, vms->newmessages, chan->language);
05314          res = res ? res : ast_play_and_wait(chan, "vm-nye");
05315          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05316       }
05317       if (!res && vms->oldmessages)
05318          res = ast_play_and_wait(chan, "vm-and");
05319    }
05320    if (!res && vms->oldmessages) {
05321       if (vms->oldmessages == 1) {
05322          res = ast_play_and_wait(chan, "digits/1");
05323          res = res ? res : ast_play_and_wait(chan, "vm-gamel");
05324          res = res ? res : ast_play_and_wait(chan, "vm-message");
05325       } else {
05326          res = say_and_wait(chan, vms->oldmessages, chan->language);
05327          res = res ? res : ast_play_and_wait(chan, "vm-gamle");
05328          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05329       }
05330    }
05331 
05332    return res;
05333 }

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

Definition at line 5177 of file app_voicemail_odbc.c.

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

05178 {
05179    /* Introduce messages they have */
05180    int res;
05181    div_t num;
05182 
05183    if (!vms->oldmessages && !vms->newmessages) {
05184       res = ast_play_and_wait(chan, "vm-no");
05185       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05186       return res;
05187    } else {
05188       res = ast_play_and_wait(chan, "vm-youhave");
05189    }
05190 
05191    if (vms->newmessages) {
05192       num = div(vms->newmessages, 10);
05193       if (vms->newmessages == 1) {
05194          res = ast_play_and_wait(chan, "digits/1-a");
05195          res = res ? res : ast_play_and_wait(chan, "vm-new-a");
05196          res = res ? res : ast_play_and_wait(chan, "vm-message");
05197       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05198          if (num.rem == 2) {
05199             if (!num.quot) {
05200                res = ast_play_and_wait(chan, "digits/2-ie");
05201             } else {
05202                res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
05203                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05204             }
05205          } else {
05206             res = say_and_wait(chan, vms->newmessages, chan->language);
05207          }
05208          res = res ? res : ast_play_and_wait(chan, "vm-new-e");
05209          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05210       } else {
05211          res = say_and_wait(chan, vms->newmessages, chan->language);
05212          res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
05213          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05214       }
05215       if (!res && vms->oldmessages)
05216          res = ast_play_and_wait(chan, "vm-and");
05217    }
05218    if (!res && vms->oldmessages) {
05219       num = div(vms->oldmessages, 10);
05220       if (vms->oldmessages == 1) {
05221          res = ast_play_and_wait(chan, "digits/1-a");
05222          res = res ? res : ast_play_and_wait(chan, "vm-old-a");
05223          res = res ? res : ast_play_and_wait(chan, "vm-message");
05224       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05225          if (num.rem == 2) {
05226             if (!num.quot) {
05227                res = ast_play_and_wait(chan, "digits/2-ie");
05228             } else {
05229                res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
05230                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05231             }
05232          } else {
05233             res = say_and_wait(chan, vms->oldmessages, chan->language);
05234          }
05235          res = res ? res : ast_play_and_wait(chan, "vm-old-e");
05236          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05237       } else {
05238          res = say_and_wait(chan, vms->oldmessages, chan->language);
05239          res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
05240          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05241       }
05242    }
05243 
05244    return res;
05245 }

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

Definition at line 5580 of file app_voicemail_odbc.c.

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

05581 {
05582    /* Introduce messages they have */
05583    int res;
05584    res = ast_play_and_wait(chan, "vm-youhave");
05585    if (!res) {
05586       if (vms->newmessages) {
05587          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
05588          if (!res) {
05589             if ((vms->newmessages == 1)) {
05590                res = ast_play_and_wait(chan, "vm-message");
05591                if (!res)
05592                   res = ast_play_and_wait(chan, "vm-INBOXs");
05593             } else {
05594                res = ast_play_and_wait(chan, "vm-messages");
05595                if (!res)
05596                   res = ast_play_and_wait(chan, "vm-INBOX");
05597             }
05598          }
05599          if (vms->oldmessages && !res)
05600             res = ast_play_and_wait(chan, "vm-and");
05601       }
05602       if (!res && vms->oldmessages) {
05603          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
05604          if (!res) {
05605             if (vms->oldmessages == 1) {
05606                res = ast_play_and_wait(chan, "vm-message");
05607                if (!res)
05608                   res = ast_play_and_wait(chan, "vm-Olds");
05609             } else {
05610                res = ast_play_and_wait(chan, "vm-messages");
05611                if (!res)
05612                   res = ast_play_and_wait(chan, "vm-Old");
05613             }
05614          }
05615       }
05616       if (!res) {
05617          if (!vms->oldmessages && !vms->newmessages) {
05618             res = ast_play_and_wait(chan, "vm-no");
05619             if (!res)
05620                res = ast_play_and_wait(chan, "vm-messages");
05621          }
05622       }
05623    }
05624    return res;
05625 }

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

Definition at line 5438 of file app_voicemail_odbc.c.

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

05438                                                                          {
05439    /* Introduce messages they have */
05440    int res;
05441    if (!vms->oldmessages && !vms->newmessages) {
05442       res = ast_play_and_wait(chan, "vm-nomessages");
05443       return res;
05444    }
05445    else {
05446       res = ast_play_and_wait(chan, "vm-youhave");
05447    }
05448    if (vms->newmessages) {
05449       if (!res)
05450          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
05451       if ((vms->newmessages == 1)) {
05452          if (!res)
05453             res = ast_play_and_wait(chan, "vm-message");
05454          if (!res)
05455             res = ast_play_and_wait(chan, "vm-INBOXs");
05456       }
05457       else {
05458          if (!res)
05459             res = ast_play_and_wait(chan, "vm-messages");
05460          if (!res)
05461             res = ast_play_and_wait(chan, "vm-INBOX");
05462       }
05463       if (vms->oldmessages && !res)
05464          res = ast_play_and_wait(chan, "vm-and");
05465    }
05466    if (vms->oldmessages) {
05467       if (!res)
05468          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
05469       if (vms->oldmessages == 1) {
05470          if (!res)
05471             res = ast_play_and_wait(chan, "vm-message");
05472          if (!res)
05473             res = ast_play_and_wait(chan, "vm-Olds");
05474       }
05475       else {
05476          if (!res)
05477       res = ast_play_and_wait(chan, "vm-messages");
05478          if (!res)
05479             res = ast_play_and_wait(chan, "vm-Old");
05480       }
05481    }
05482    return res;
05483 }

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

Definition at line 5709 of file app_voicemail_odbc.c.

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

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

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

Definition at line 5248 of file app_voicemail_odbc.c.

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

05249 {
05250    /* Introduce messages they have */
05251    int res;
05252 
05253    res = ast_play_and_wait(chan, "vm-youhave");
05254    if (res)
05255       return res;
05256 
05257    if (!vms->oldmessages && !vms->newmessages) {
05258       res = ast_play_and_wait(chan, "vm-no");
05259       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05260       return res;
05261    }
05262 
05263    if (vms->newmessages) {
05264       if ((vms->newmessages == 1)) {
05265          res = ast_play_and_wait(chan, "digits/ett");
05266          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
05267          res = res ? res : ast_play_and_wait(chan, "vm-message");
05268       } else {
05269          res = say_and_wait(chan, vms->newmessages, chan->language);
05270          res = res ? res : ast_play_and_wait(chan, "vm-nya");
05271          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05272       }
05273       if (!res && vms->oldmessages)
05274          res = ast_play_and_wait(chan, "vm-and");
05275    }
05276    if (!res && vms->oldmessages) {
05277       if (vms->oldmessages == 1) {
05278          res = ast_play_and_wait(chan, "digits/ett");
05279          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
05280          res = res ? res : ast_play_and_wait(chan, "vm-message");
05281       } else {
05282          res = say_and_wait(chan, vms->oldmessages, chan->language);
05283          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
05284          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05285       }
05286    }
05287 
05288    return res;
05289 }

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

Definition at line 5783 of file app_voicemail_odbc.c.

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

05784 {
05785    int res;
05786    int lastnum = 0;
05787    int dcnum;
05788 
05789    res = ast_play_and_wait(chan, "vm-youhave");
05790    if (!res && vms->newmessages) {
05791       lastnum = get_lastdigits(vms->newmessages);
05792       dcnum = vms->newmessages - lastnum;
05793       if (dcnum)
05794          res = say_and_wait(chan, dcnum, chan->language);
05795       if (!res && lastnum) {
05796          if (lastnum == 1) 
05797             res = ast_play_and_wait(chan, "digits/ua/1e");
05798          else
05799             res = say_and_wait(chan, lastnum, chan->language);
05800       }
05801 
05802       if (!res)
05803          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-nove" : "vm-INBOX");
05804 
05805       if (!res && vms->oldmessages)
05806          res = ast_play_and_wait(chan, "vm-and");
05807    }
05808 
05809    if (!res && vms->oldmessages) {
05810       lastnum = get_lastdigits(vms->oldmessages);
05811       dcnum = vms->oldmessages - lastnum;
05812       if (dcnum)
05813          res = say_and_wait(chan, dcnum, chan->language);
05814       if (!res && lastnum) {
05815          if (lastnum == 1) 
05816             res = ast_play_and_wait(chan, "digits/ua/1e");
05817          else
05818             res = say_and_wait(chan, lastnum, chan->language);
05819       }
05820 
05821       if (!res)
05822          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-stare" : "vm-Old");
05823    }
05824 
05825    if (!res && !vms->newmessages && !vms->oldmessages) {
05826       lastnum = 0;
05827       res = ast_play_and_wait(chan, "vm-no");
05828    }
05829 
05830    if (!res) {
05831       switch (lastnum) {
05832       case 1:
05833       case 2:
05834       case 3:
05835       case 4:
05836          res = ast_play_and_wait(chan, "vm-message");
05837          break;
05838       default:
05839          res = ast_play_and_wait(chan, "vm-messages");
05840          break;
05841       }
05842    }
05843 
05844    return res;
05845 }

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

Definition at line 959 of file app_voicemail_odbc.c.

References ast_lock_path(), and AST_LOCK_TIMEOUT.

00960 {
00961    switch (ast_lock_path(path)) {
00962    case AST_LOCK_TIMEOUT:
00963       return -1;
00964    default:
00965       return 0;
00966    }
00967 }

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

Definition at line 1770 of file app_voicemail_odbc.c.

References VOICEMAIL_FILE_MODE.

01771 {
01772    FILE *p = NULL;
01773    int pfd = mkstemp(template);
01774    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
01775    if (pfd > -1) {
01776       p = fdopen(pfd, "w+");
01777       if (!p) {
01778          close(pfd);
01779          pfd = -1;
01780       }
01781    }
01782    return p;
01783 }

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 5940 of file app_voicemail_odbc.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, LOG_DEBUG, LOG_NOTICE, option_debug, play_record_review(), vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, and VM_FORCENAME.

05941 {
05942    int cmd = 0;
05943    int duration = 0;
05944    int tries = 0;
05945    char newpassword[80] = "";
05946    char newpassword2[80] = "";
05947    char prefile[PATH_MAX] = "";
05948    unsigned char buf[256];
05949    int bytes=0;
05950 
05951    if (ast_adsi_available(chan)) {
05952       bytes += adsi_logo(buf + bytes);
05953       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
05954       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
05955       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05956       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05957       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05958    }
05959 
05960    /* First, have the user change their password 
05961       so they won't get here again */
05962    for (;;) {
05963       newpassword[1] = '\0';
05964       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
05965       if (cmd == '#')
05966          newpassword[0] = '\0';
05967       if (cmd < 0 || cmd == 't' || cmd == '#')
05968          return cmd;
05969       cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
05970       if (cmd < 0 || cmd == 't' || cmd == '#')
05971          return cmd;
05972       newpassword2[1] = '\0';
05973       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
05974       if (cmd == '#')
05975          newpassword2[0] = '\0';
05976       if (cmd < 0 || cmd == 't' || cmd == '#')
05977          return cmd;
05978       cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
05979       if (cmd < 0 || cmd == 't' || cmd == '#')
05980          return cmd;
05981       if (!strcmp(newpassword, newpassword2))
05982          break;
05983       ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
05984       cmd = ast_play_and_wait(chan, "vm-mismatch");
05985       if (++tries == 3)
05986          return -1;
05987    }
05988    if (ast_strlen_zero(ext_pass_cmd)) 
05989       vm_change_password(vmu,newpassword);
05990    else 
05991       vm_change_password_shell(vmu,newpassword);
05992    if (option_debug > 2)
05993       ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
05994    cmd = ast_play_and_wait(chan,"vm-passchanged");
05995 
05996    /* If forcename is set, have the user record their name */  
05997    if (ast_test_flag(vmu, VM_FORCENAME)) {
05998       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
05999       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06000 #ifndef IMAP_STORAGE
06001          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06002 #else
06003          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06004 #endif
06005          if (cmd < 0 || cmd == 't' || cmd == '#')
06006             return cmd;
06007       }
06008    }
06009 
06010    /* If forcegreetings is set, have the user record their greetings */
06011    if (ast_test_flag(vmu, VM_FORCEGREET)) {
06012       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06013       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06014 #ifndef IMAP_STORAGE
06015          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06016 #else
06017          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06018 #endif
06019          if (cmd < 0 || cmd == 't' || cmd == '#')
06020             return cmd;
06021       }
06022 
06023       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06024       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06025 #ifndef IMAP_STORAGE
06026          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06027 #else
06028          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06029 #endif
06030          if (cmd < 0 || cmd == 't' || cmd == '#')
06031             return cmd;
06032       }
06033    }
06034 
06035    return cmd;
06036 }

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 6038 of file app_voicemail_odbc.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_waitfordigit(), ast_vm_user::context, LOG_DEBUG, LOG_NOTICE, option_debug, ast_vm_user::password, play_record_review(), vm_state::username, vm_change_password(), vm_change_password_shell(), and vm_tempgreeting().

06039 {
06040    int cmd = 0;
06041    int retries = 0;
06042    int duration = 0;
06043    char newpassword[80] = "";
06044    char newpassword2[80] = "";
06045    char prefile[PATH_MAX] = "";
06046    unsigned char buf[256];
06047    int bytes=0;
06048 
06049    if (ast_adsi_available(chan))
06050    {
06051       bytes += adsi_logo(buf + bytes);
06052       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
06053       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06054       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06055       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06056       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06057    }
06058    while ((cmd >= 0) && (cmd != 't')) {
06059       if (cmd)
06060          retries = 0;
06061       switch (cmd) {
06062       case '1':
06063          snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06064 #ifndef IMAP_STORAGE
06065          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06066 #else
06067          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06068 #endif
06069          break;
06070       case '2': 
06071          snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06072 #ifndef IMAP_STORAGE
06073          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06074 #else
06075          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06076 #endif
06077          break;
06078       case '3': 
06079          snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06080 #ifndef IMAP_STORAGE
06081          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06082 #else
06083          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06084 #endif
06085          break;
06086       case '4': 
06087          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
06088          break;
06089       case '5':
06090          if (vmu->password[0] == '-') {
06091             cmd = ast_play_and_wait(chan, "vm-no");
06092             break;
06093          }
06094          newpassword[1] = '\0';
06095          newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06096          if (cmd == '#')
06097             newpassword[0] = '\0';
06098          else {
06099             if (cmd < 0)
06100                break;
06101             if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
06102                break;
06103             }
06104          }
06105          newpassword2[1] = '\0';
06106          newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06107          if (cmd == '#')
06108             newpassword2[0] = '\0';
06109          else {
06110             if (cmd < 0)
06111                break;
06112 
06113             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#"))) {
06114                break;
06115             }
06116          }
06117          if (strcmp(newpassword, newpassword2)) {
06118             ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
06119             cmd = ast_play_and_wait(chan, "vm-mismatch");
06120             break;
06121          }
06122          if (ast_strlen_zero(ext_pass_cmd)) 
06123             vm_change_password(vmu,newpassword);
06124          else 
06125             vm_change_password_shell(vmu,newpassword);
06126          if (option_debug > 2)
06127             ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
06128          cmd = ast_play_and_wait(chan,"vm-passchanged");
06129          break;
06130       case '*': 
06131          cmd = 't';
06132          break;
06133       default: 
06134          cmd = 0;
06135          snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06136          if (ast_fileexists(prefile, NULL, NULL))
06137             cmd = ast_play_and_wait(chan, "vm-tmpexists");
06138          if (!cmd)
06139             cmd = ast_play_and_wait(chan, "vm-options");
06140          if (!cmd)
06141             cmd = ast_waitfordigit(chan,6000);
06142          if (!cmd)
06143             retries++;
06144          if (retries > 3)
06145             cmd = 't';
06146       }
06147    }
06148    if (cmd == 't')
06149       cmd = 0;
06150    return cmd;
06151 }

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

Definition at line 5029 of file app_voicemail_odbc.c.

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

05030 {
05031    int cmd;
05032 
05033    if (!strcasecmp(chan->language, "it") || !strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) { /* Italian, Spanish, French or Portuguese syntax */
05034       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
05035       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05036    } else if (!strcasecmp(chan->language, "gr")){
05037       return vm_play_folder_name_gr(chan, mbox);
05038    } else if (!strcasecmp(chan->language, "pl")){
05039       return vm_play_folder_name_pl(chan, mbox);
05040    } else if (!strcasecmp(chan->language, "ua")){  /* Ukrainian syntax */
05041       return vm_play_folder_name_ua(chan, mbox);
05042    } else {  /* Default English */
05043       cmd = ast_play_and_wait(chan, mbox);
05044       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
05045    }
05046 }

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

Definition at line 4982 of file app_voicemail_odbc.c.

References ast_play_and_wait().

04983 {
04984    int cmd;
04985    char *buf;
04986 
04987    buf = alloca(strlen(mbox)+2); 
04988    strcpy(buf, mbox);
04989    strcat(buf,"s");
04990 
04991    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
04992       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
04993       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
04994    } else {
04995       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
04996       return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
04997    }
04998 }

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

Definition at line 5000 of file app_voicemail_odbc.c.

References ast_play_and_wait().

05001 {
05002    int cmd;
05003 
05004    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
05005       if (!strcasecmp(mbox, "vm-INBOX"))
05006          cmd = ast_play_and_wait(chan, "vm-new-e");
05007       else
05008          cmd = ast_play_and_wait(chan, "vm-old-e");
05009       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05010    } else {
05011       cmd = ast_play_and_wait(chan, "vm-messages");
05012       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05013    }
05014 }

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

Definition at line 5016 of file app_voicemail_odbc.c.

References ast_play_and_wait().

05017 {
05018    int cmd;
05019 
05020    if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")){
05021       cmd = ast_play_and_wait(chan, "vm-messages");
05022       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05023    } else {
05024       cmd = ast_play_and_wait(chan, mbox);
05025       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05026    }
05027 }

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 6153 of file app_voicemail_odbc.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, play_record_review(), RETRIEVE, and vm_state::username.

06154 {
06155    int res;
06156    int cmd = 0;
06157    int retries = 0;
06158    int duration = 0;
06159    char prefile[PATH_MAX] = "";
06160    unsigned char buf[256];
06161    char dest[PATH_MAX];
06162    int bytes = 0;
06163 
06164    if (ast_adsi_available(chan)) {
06165       bytes += adsi_logo(buf + bytes);
06166       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
06167       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06168       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06169       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06170       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06171    }
06172 
06173    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06174    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
06175       ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
06176       return -1;
06177    }
06178    while ((cmd >= 0) && (cmd != 't')) {
06179       if (cmd)
06180          retries = 0;
06181       RETRIEVE(prefile, -1);
06182       if (ast_fileexists(prefile, NULL, NULL) <= 0) {
06183 #ifndef IMAP_STORAGE
06184          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06185 #else
06186          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06187 #endif
06188          cmd = 't';  
06189       } else {
06190          switch (cmd) {
06191          case '1':
06192 #ifndef IMAP_STORAGE
06193             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06194 #else
06195             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06196 #endif
06197             break;
06198          case '2':
06199             DELETE(prefile, -1, prefile);
06200             ast_play_and_wait(chan, "vm-tempremoved");
06201             cmd = 't';  
06202             break;
06203          case '*': 
06204             cmd = 't';
06205             break;
06206          default:
06207             cmd = ast_play_and_wait(chan,
06208                ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
06209                   "vm-tempgreeting2" : "vm-tempgreeting");
06210             if (!cmd)
06211                cmd = ast_waitfordigit(chan,6000);
06212             if (!cmd)
06213                retries++;
06214             if (retries > 3)
06215                cmd = 't';
06216          }
06217       }
06218       DISPOSE(prefile, -1);
06219    }
06220    if (cmd == 't')
06221       cmd = 0;
06222    return cmd;
06223 }

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

Definition at line 7204 of file app_voicemail_odbc.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().

07205 {
07206    struct ast_module_user *u;
07207    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
07208    struct ast_vm_user vmus;
07209    char *options = NULL;
07210    int silent = 0, skipuser = 0;
07211    int res = -1;
07212 
07213    u = ast_module_user_add(chan);
07214    
07215    if (s) {
07216       s = ast_strdupa(s);
07217       user = strsep(&s, "|");
07218       options = strsep(&s, "|");
07219       if (user) {
07220          s = user;
07221          user = strsep(&s, "@");
07222          context = strsep(&s, "");
07223          if (!ast_strlen_zero(user))
07224             skipuser++;
07225          ast_copy_string(mailbox, user, sizeof(mailbox));
07226       }
07227    }
07228 
07229    if (options) {
07230       silent = (strchr(options, 's')) != NULL;
07231    }
07232 
07233    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
07234       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
07235       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
07236       ast_play_and_wait(chan, "auth-thankyou");
07237       res = 0;
07238    }
07239 
07240    ast_module_user_remove(u);
07241    return res;
07242 }

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

Definition at line 1750 of file app_voicemail_odbc.c.

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

01751 {
01752    const struct vm_zone *z = NULL;
01753    time_t t = time(NULL);
01754 
01755    /* Does this user have a timezone specified? */
01756    if (!ast_strlen_zero(vmu->zonetag)) {
01757       /* Find the zone in the list */
01758       AST_LIST_LOCK(&zones);
01759       AST_LIST_TRAVERSE(&zones, z, list) {
01760          if (!strcmp(z->name, vmu->zonetag))
01761             break;
01762       }
01763       AST_LIST_UNLOCK(&zones);
01764    }
01765    ast_localtime(&t, tm, z ? z->timezone : NULL);
01766    return tm;
01767 }

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

Definition at line 4277 of file app_voicemail_odbc.c.

References ast_control_streamfile().

04278 {
04279    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
04280 }

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

Definition at line 4269 of file app_voicemail_odbc.c.

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

04270 {
04271    int res;
04272    if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0) 
04273       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
04274    return res;
04275 }


Variable Documentation

char* addesc = "Comedian Mail" [static]

Definition at line 448 of file app_voicemail_odbc.c.

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

Definition at line 569 of file app_voicemail_odbc.c.

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

Definition at line 570 of file app_voicemail_odbc.c.

int adsiver = 1 [static]

Definition at line 571 of file app_voicemail_odbc.c.

char* app = "VoiceMail" [static]

Definition at line 524 of file app_voicemail_odbc.c.

char* app2 = "VoiceMailMain" [static]

Definition at line 527 of file app_voicemail_odbc.c.

char* app3 = "MailboxExists" [static]

Definition at line 529 of file app_voicemail_odbc.c.

char* app4 = "VMAuthenticate" [static]

Definition at line 530 of file app_voicemail_odbc.c.

char callcontext[AST_MAX_CONTEXT] [static]

Definition at line 554 of file app_voicemail_odbc.c.

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

Definition at line 567 of file app_voicemail_odbc.c.

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static]

Definition at line 557 of file app_voicemail_odbc.c.

Initial value:

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

Definition at line 7346 of file app_voicemail_odbc.c.

Initial value:

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

Definition at line 7351 of file app_voicemail_odbc.c.

struct ast_cli_entry cli_voicemail[] [static]

Definition at line 7356 of file app_voicemail_odbc.c.

char* descrip_vm [static]

Definition at line 453 of file app_voicemail_odbc.c.

char* descrip_vm_box_exists [static]

Definition at line 499 of file app_voicemail_odbc.c.

char* descrip_vmain [static]

Definition at line 481 of file app_voicemail_odbc.c.

char* descrip_vmauthenticate [static]

Definition at line 513 of file app_voicemail_odbc.c.

char dialcontext[AST_MAX_CONTEXT] [static]

Definition at line 553 of file app_voicemail_odbc.c.

char* emailbody = NULL [static]

Definition at line 560 of file app_voicemail_odbc.c.

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

Definition at line 572 of file app_voicemail_odbc.c.

char* emailsubject = NULL [static]

Definition at line 561 of file app_voicemail_odbc.c.

char emailtitle[100] [static]

Definition at line 566 of file app_voicemail_odbc.c.

char exitcontext[AST_MAX_CONTEXT] [static]

Definition at line 555 of file app_voicemail_odbc.c.

char ext_pass_cmd[128] [static]

Definition at line 434 of file app_voicemail_odbc.c.

char externnotify[160] [static]

Definition at line 539 of file app_voicemail_odbc.c.

char fromstring[100] [static]

Definition at line 564 of file app_voicemail_odbc.c.

struct ast_flags globalflags = {0} [static]

Definition at line 549 of file app_voicemail_odbc.c.

char mailcmd[160] [static]

Definition at line 538 of file app_voicemail_odbc.c.

int maxgreet [static]

Definition at line 545 of file app_voicemail_odbc.c.

int maxlogins [static]

Definition at line 547 of file app_voicemail_odbc.c.

int maxmsg [static]

Definition at line 535 of file app_voicemail_odbc.c.

int maxsilence [static]

Definition at line 534 of file app_voicemail_odbc.c.

int my_umask

Definition at line 436 of file app_voicemail_odbc.c.

char* pagerbody = NULL [static]

Definition at line 562 of file app_voicemail_odbc.c.

char pagerfromstring[100] [static]

Definition at line 565 of file app_voicemail_odbc.c.

char* pagersubject = NULL [static]

Definition at line 563 of file app_voicemail_odbc.c.

int saydurationminfo [static]

Definition at line 551 of file app_voicemail_odbc.c.

char serveremail[80] [static]

Definition at line 537 of file app_voicemail_odbc.c.

int silencethreshold = 128 [static]

Definition at line 536 of file app_voicemail_odbc.c.

int skipms [static]

Definition at line 546 of file app_voicemail_odbc.c.

struct ast_smdi_interface* smdi_iface = NULL [static]

Definition at line 540 of file app_voicemail_odbc.c.

char* synopsis_vm [static]

Initial value:

"Leave a Voicemail message"

Definition at line 450 of file app_voicemail_odbc.c.

char* synopsis_vm_box_exists [static]

Initial value:

"Check to see if Voicemail mailbox exists"

Definition at line 496 of file app_voicemail_odbc.c.

char* synopsis_vmain [static]

Initial value:

"Check Voicemail messages"

Definition at line 478 of file app_voicemail_odbc.c.

char* synopsis_vmauthenticate [static]

Initial value:

"Authenticate with Voicemail passwords"

Definition at line 510 of file app_voicemail_odbc.c.

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

Definition at line 446 of file app_voicemail_odbc.c.

enum { ... } vm_option_args

enum { ... } vm_option_flags

char VM_SPOOL_DIR[PATH_MAX] [static]

Definition at line 432 of file app_voicemail_odbc.c.

char vmfmts[80] [static]

Definition at line 541 of file app_voicemail_odbc.c.

int vmmaxmessage [static]

Definition at line 544 of file app_voicemail_odbc.c.

int vmminmessage [static]

Definition at line 543 of file app_voicemail_odbc.c.

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 7244 of file app_voicemail_odbc.c.

char voicemail_show_zones_help[] [static]

Initial value:

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

Definition at line 7248 of file app_voicemail_odbc.c.

double volgain [static]

Definition at line 542 of file app_voicemail_odbc.c.


Generated on Sun Jun 12 16:37:51 2011 for Asterisk - the Open Source PBX by  doxygen 1.5.6