Fri Sep 29 11:13:00 2006

Asterisk developer's documentation


app_voicemail.c File Reference

Comedian Mail - Voicemail System. More...

#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.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 dependency graph for app_voicemail.c:

Go to the source code of this file.

Data Structures

struct  ast_vm_user
struct  baseio
struct  leave_vm_options
struct  vm_state
struct  vm_zone

Defines

#define ASTERISK_USERNAME   "asterisk"
#define BASELINELEN   72
#define BASEMAXINLINE   256
#define BASEMAXINLINE   256
#define COMMAND_TIMEOUT   5000
#define COPY(a, b, c, d, e, f, g, h)   (copy_file(g,h));
#define DELETE(a, b, c)   (vm_delete(c))
#define DISPOSE(a, b)
#define eol   "\r\n"
#define ERROR_LOCK_PATH   -100
#define EXISTS(a, b, c, d)   (ast_fileexists(c,NULL,d) > 0)
#define INTRO   "vm-intro"
#define MAX_DATETIME_FORMAT   512
#define MAX_NUM_CID_CONTEXTS   10
#define MAXMSG   100
#define MAXMSGLIMIT   9999
#define RENAME(a, b, c, d, e, f, g, h)   (rename_file(g,h));
#define RETRIEVE(a, b)
#define SENDMAIL   "/usr/sbin/sendmail -t"
#define STORE(a, b, c, d)
#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 VOICEMAIL_CONFIG   "voicemail.conf"
#define VOICEMAIL_DIR_MODE   0700
#define VOICEMAIL_FILE_MODE   0600

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)
}
enum  { OPT_ARG_RECORDGAIN = 0, OPT_ARG_ARRAY_SIZE = 1 }

Functions

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)
 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_MUTEX_DEFINE_STATIC (vmlock)
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_show_voicemail_users (char *line, char *word, int pos, int state)
static int copy (char *infile, char *outfile)
static void copy_file (char *frompath, char *topath)
static int copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt)
static int count_messages (struct ast_vm_user *vmu, char *dir)
static int create_dirpath (char *dest, int len, char *context, char *ext, char *mailbox)
char * description (void)
 Provides a description of the module.
static int dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
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, char *dir, int curmsg, 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 handle_show_voicemail_users (int fd, int argc, char *argv[])
static int handle_show_voicemail_zones (int fd, int argc, char *argv[])
static int has_voicemail (const char *mailbox, const char *folder)
static int inbuf (struct baseio *bio, FILE *fi)
static int inchar (struct baseio *bio, FILE *fi)
static int invent_message (struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes)
char * key ()
 Returns the ASTERISK_GPL_KEY.
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)
int load_module (void)
 Initialize the module.
static int make_dir (char *dest, int len, char *context, char *ext, char *mailbox)
static int make_file (char *dest, int len, char *dir, int num)
static char * mbox (int id)
static int messagecount (const char *mailbox, int *newmsgs, int *oldmsgs)
static int notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
static int ochar (struct baseio *bio, int c, FILE *so)
static int open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box)
static int play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, char *context, int callback)
static int play_message_category (struct ast_channel *chan, char *category)
static int play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, char *origtime, char *filename)
static int play_message_duration (struct ast_channel *chan, struct vm_state *vms, 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)
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)
int reload (void)
 Reload stuff.
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, char *dir, int msg, char *context, char *username, int box)
static int say_and_wait (struct ast_channel *chan, int num, 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)
static int sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu)
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.
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 *vmfts, char *context, signed char record_gain)
static int vm_instructions (struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
static int vm_intro (struct ast_channel *chan, 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_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_se (struct ast_channel *chan, struct vm_state *vms)
static int vm_lock_path (const char *path)
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_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 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 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}
 LOCAL_USER_DECL
static char mailcmd [160]
static int maxgreet
static int maxlogins
static int maxmsg
static int maxsilence
static char * pagerbody = NULL
static char pagerfromstring [100]
static char * pagersubject = NULL
static int saydurationminfo
static char serveremail [80]
static struct ast_cli_entry show_voicemail_users_cli
static char show_voicemail_users_help []
static struct ast_cli_entry show_voicemail_zones_cli
static char show_voicemail_zones_help []
static int silencethreshold = 128
static int skipms
 STANDARD_LOCAL_USER
static char * synopsis_vm
static char * synopsis_vm_box_exists
static char * synopsis_vmain
static char * synopsis_vmauthenticate
static char * tdesc = "Comedian Mail (Voicemail System)"
ast_vm_userusers
ast_vm_userusersl
enum { ... }  vm_option_args
enum { ... }  vm_option_flags
static char VM_SPOOL_DIR [AST_CONFIG_MAX_PATH]
static char vmfmts [80]
static int vmmaxmessage
static int vmminmessage
vm_zonezones = NULL
vm_zonezonesl = NULL


Detailed Description

Comedian Mail - Voicemail System.

See also

Definition in file app_voicemail.c.


Define Documentation

#define ASTERISK_USERNAME   "asterisk"

Definition at line 82 of file app_voicemail.c.

Referenced by load_config().

#define BASELINELEN   72

Definition at line 94 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 95 of file app_voicemail.c.

#define BASEMAXINLINE   256

Definition at line 95 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define COMMAND_TIMEOUT   5000

Definition at line 77 of file app_voicemail.c.

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

Definition at line 287 of file app_voicemail.c.

Referenced by copy_message().

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

Definition at line 288 of file app_voicemail.c.

Referenced by notify_new_message(), play_record_review(), and vm_tempgreeting().

#define DISPOSE ( a,
 ) 

Definition at line 283 of file app_voicemail.c.

Referenced by advanced_options(), invent_message(), leave_voicemail(), play_message(), play_record_review(), and vm_tempgreeting().

#define eol   "\r\n"

Definition at line 96 of file app_voicemail.c.

Referenced by base_encode(), and ochar().

#define ERROR_LOCK_PATH   -100

Definition at line 117 of file app_voicemail.c.

Referenced by close_mailbox(), copy_message(), count_messages(), forward_message(), last_message_index(), resequence_mailbox(), save_to_folder(), vm_exec(), and vm_execmain().

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

Definition at line 285 of file app_voicemail.c.

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

#define INTRO   "vm-intro"

Definition at line 88 of file app_voicemail.c.

Referenced by leave_voicemail(), and play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 98 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 99 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 90 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

Definition at line 91 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

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

Definition at line 286 of file app_voicemail.c.

Referenced by close_mailbox(), and resequence_mailbox().

#define RETRIEVE ( a,
 ) 

Definition at line 282 of file app_voicemail.c.

Referenced by advanced_options(), forward_message(), invent_message(), leave_voicemail(), play_message(), and vm_tempgreeting().

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

Definition at line 86 of file app_voicemail.c.

Referenced by load_config().

#define STORE ( a,
b,
c,
 ) 

Definition at line 284 of file app_voicemail.c.

Referenced by forward_message(), leave_voicemail(), and play_record_review().

#define VM_ALLOCED   (1 << 13)

Definition at line 114 of file app_voicemail.c.

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

#define VM_ATTACH   (1 << 11)

Definition at line 112 of file app_voicemail.c.

Referenced by apply_option(), forward_message(), load_config(), notify_new_message(), and sendmail().

#define VM_DELETE   (1 << 12)

Definition at line 113 of file app_voicemail.c.

Referenced by apply_option(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 111 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

Definition at line 105 of file app_voicemail.c.

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

#define VM_FORCEGREET   (1 << 8)

Have new users record their greetings

Definition at line 109 of file app_voicemail.c.

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

#define VM_FORCENAME   (1 << 7)

Have new users record their name

Definition at line 108 of file app_voicemail.c.

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

#define VM_OPERATOR   (1 << 1)

Definition at line 102 of file app_voicemail.c.

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

#define VM_PBXSKIP   (1 << 9)

Definition at line 110 of file app_voicemail.c.

Referenced by load_config(), and sendmail().

#define VM_REVIEW   (1 << 0)

Definition at line 101 of file app_voicemail.c.

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

#define VM_SAYCID   (1 << 2)

Definition at line 103 of file app_voicemail.c.

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

#define VM_SAYDURATION   (1 << 5)

Definition at line 106 of file app_voicemail.c.

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

#define VM_SEARCH   (1 << 14)

Definition at line 115 of file app_voicemail.c.

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

#define VM_SKIPAFTERCMD   (1 << 6)

Definition at line 107 of file app_voicemail.c.

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

Definition at line 104 of file app_voicemail.c.

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

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 81 of file app_voicemail.c.

#define VOICEMAIL_DIR_MODE   0700

Definition at line 78 of file app_voicemail.c.

Referenced by create_dirpath().

#define VOICEMAIL_FILE_MODE   0600

Definition at line 79 of file app_voicemail.c.

Referenced by copy().


Enumeration Type Documentation

anonymous enum

Enumerator:
OPT_SILENT 
OPT_BUSY_GREETING 
OPT_UNAVAIL_GREETING 
OPT_RECORDGAIN 
OPT_PREPEND_MAILBOX 
OPT_PRIORITY_JUMP 

Definition at line 119 of file app_voicemail.c.

00119      {
00120    OPT_SILENT =           (1 << 0),
00121    OPT_BUSY_GREETING =    (1 << 1),
00122    OPT_UNAVAIL_GREETING = (1 << 2),
00123    OPT_RECORDGAIN =       (1 << 3),
00124    OPT_PREPEND_MAILBOX =  (1 << 4),
00125    OPT_PRIORITY_JUMP =    (1 << 5),
00126 } vm_option_flags;

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_ARRAY_SIZE 

Definition at line 128 of file app_voicemail.c.

00128      {
00129    OPT_ARG_RECORDGAIN = 0,
00130    OPT_ARG_ARRAY_SIZE = 1,
00131 } vm_option_args;


Function Documentation

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

Definition at line 2887 of file app_voicemail.c.

References adsi_available(), adsi_load_session(), adsi_load_vmail(), ast_log(), and LOG_WARNING.

Referenced by vm_authenticate(), and vm_execmain().

02888 {
02889    int x;
02890    if (!adsi_available(chan))
02891       return;
02892    x = adsi_load_session(chan, adsifdn, adsiver, 1);
02893    if (x < 0)
02894       return;
02895    if (!x) {
02896       if (adsi_load_vmail(chan, useadsi)) {
02897          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
02898          return;
02899       }
02900    } else
02901       *useadsi = 1;
02902 }

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

Definition at line 3074 of file app_voicemail.c.

References adsi_available(), ADSI_KEY_APPS, ADSI_KEY_SKT, vm_state::curmsg, and keys.

Referenced by vm_execmain().

03075 {
03076    int bytes=0;
03077    unsigned char buf[256];
03078    unsigned char keys[8];
03079 
03080    int x;
03081 
03082    if (!adsi_available(chan))
03083       return;
03084 
03085    /* New meaning for keys */
03086    for (x=0;x<5;x++)
03087       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
03088 
03089    keys[6] = 0x0;
03090    keys[7] = 0x0;
03091 
03092    if (!vms->curmsg) {
03093       /* No prev key, provide "Folder" instead */
03094       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03095    }
03096    if (vms->curmsg >= vms->lastmsg) {
03097       /* If last message ... */
03098       if (vms->curmsg) {
03099          /* but not only message, provide "Folder" instead */
03100          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03101       } else {
03102          /* Otherwise if only message, leave blank */
03103          keys[3] = 1;
03104       }
03105    }
03106 
03107    /* If deleted, show "undeleted" */
03108    if (vms->deleted[vms->curmsg]) 
03109       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
03110 
03111    /* Except "Exit" */
03112    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
03113    bytes += adsi_set_keys(buf + bytes, keys);
03114    bytes += adsi_voice_mode(buf + bytes, 0);
03115 
03116    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03117 }

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

Definition at line 2952 of file app_voicemail.c.

References adsi_available(), ADSI_COMM_PAGE, adsi_display(), ADSI_JUST_CENT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, adsi_set_keys(), adsi_set_line(), adsi_transmit_message(), adsi_voice_mode(), and keys.

Referenced by vm_execmain().

02953 {
02954    unsigned char buf[256];
02955    int bytes=0;
02956    unsigned char keys[8];
02957    int x,y;
02958 
02959    if (!adsi_available(chan))
02960       return;
02961 
02962    for (x=0;x<5;x++) {
02963       y = ADSI_KEY_APPS + 12 + start + x;
02964       if (y > ADSI_KEY_APPS + 12 + 4)
02965          y = 0;
02966       keys[x] = ADSI_KEY_SKT | y;
02967    }
02968    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
02969    keys[6] = 0;
02970    keys[7] = 0;
02971 
02972    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
02973    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
02974    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02975    bytes += adsi_set_keys(buf + bytes, keys);
02976    bytes += adsi_voice_mode(buf + bytes, 0);
02977 
02978    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02979 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

Definition at line 3222 of file app_voicemail.c.

References adsi_available(), ADSI_COMM_PAGE, adsi_display(), ADSI_JUST_CENT, ADSI_JUST_LEFT, adsi_logo(), ADSI_MSG_DISPLAY, adsi_set_line(), adsi_transmit_message(), and adsi_voice_mode().

Referenced by vm_execmain().

03223 {
03224    unsigned char buf[256];
03225    int bytes=0;
03226 
03227    if (!adsi_available(chan))
03228       return;
03229    bytes += adsi_logo(buf + bytes);
03230    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
03231    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
03232    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03233    bytes += adsi_voice_mode(buf + bytes, 0);
03234 
03235    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03236 }

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

Definition at line 2758 of file app_voicemail.c.

References adsi_begin_download(), ADSI_COMM_PAGE, adsi_data_mode(), adsi_display(), adsi_download_disconnect(), adsi_end_download(), ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_load_session(), adsi_load_soft_key(), adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, adsi_set_line(), adsi_transmit_message(), adsi_voice_mode(), ast_log(), LOG_DEBUG, and mbox().

Referenced by adsi_begin().

02759 {
02760    unsigned char buf[256];
02761    int bytes=0;
02762    int x;
02763    char num[5];
02764 
02765    *useadsi = 0;
02766    bytes += adsi_data_mode(buf + bytes);
02767    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02768 
02769    bytes = 0;
02770    bytes += adsi_logo(buf);
02771    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
02772 #ifdef DISPLAY
02773    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
02774 #endif
02775    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02776    bytes += adsi_data_mode(buf + bytes);
02777    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02778 
02779    if (adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
02780       bytes = 0;
02781       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
02782       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
02783       bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02784       bytes += adsi_voice_mode(buf + bytes, 0);
02785       adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02786       return 0;
02787    }
02788 
02789 #ifdef DISPLAY
02790    /* Add a dot */
02791    bytes = 0;
02792    bytes += adsi_logo(buf);
02793    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
02794    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
02795    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02796    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02797 #endif
02798    bytes = 0;
02799    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
02800    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
02801    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
02802    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
02803    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
02804    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
02805    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
02806 
02807 #ifdef DISPLAY
02808    /* Add another dot */
02809    bytes = 0;
02810    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
02811    bytes += adsi_voice_mode(buf + bytes, 0);
02812 
02813    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02814    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02815 #endif
02816 
02817    bytes = 0;
02818    /* These buttons we load but don't use yet */
02819    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
02820    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
02821    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
02822    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
02823    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
02824    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
02825    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
02826 
02827 #ifdef DISPLAY
02828    /* Add another dot */
02829    bytes = 0;
02830    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
02831    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02832    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02833 #endif
02834 
02835    bytes = 0;
02836    for (x=0;x<5;x++) {
02837       snprintf(num, sizeof(num), "%d", x);
02838       bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
02839    }
02840    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
02841    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
02842 
02843 #ifdef DISPLAY
02844    /* Add another dot */
02845    bytes = 0;
02846    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
02847    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02848    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02849 #endif
02850 
02851    if (adsi_end_download(chan)) {
02852       bytes = 0;
02853       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
02854       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
02855       bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02856       bytes += adsi_voice_mode(buf + bytes, 0);
02857       adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02858       return 0;
02859    }
02860    bytes = 0;
02861    bytes += adsi_download_disconnect(buf + bytes);
02862    bytes += adsi_voice_mode(buf + bytes, 0);
02863    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
02864 
02865    ast_log(LOG_DEBUG, "Done downloading scripts...\n");
02866 
02867 #ifdef DISPLAY
02868    /* Add last dot */
02869    bytes = 0;
02870    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
02871    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02872 #endif
02873    ast_log(LOG_DEBUG, "Restarting session...\n");
02874 
02875    bytes = 0;
02876    /* Load the session now */
02877    if (adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
02878       *useadsi = 1;
02879       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
02880    } else
02881       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
02882 
02883    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02884    return 0;
02885 }

static void adsi_login ( struct ast_channel chan  )  [static]

Definition at line 2904 of file app_voicemail.c.

References adsi_available(), ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, adsi_display(), adsi_input_control(), adsi_input_format(), ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_load_soft_key(), adsi_logo(), ADSI_MSG_DISPLAY, adsi_set_keys(), adsi_set_line(), adsi_transmit_message(), adsi_voice_mode(), and keys.

Referenced by vm_authenticate().

02905 {
02906    unsigned char buf[256];
02907    int bytes=0;
02908    unsigned char keys[8];
02909    int x;
02910    if (!adsi_available(chan))
02911       return;
02912 
02913    for (x=0;x<8;x++)
02914       keys[x] = 0;
02915    /* Set one key for next */
02916    keys[3] = ADSI_KEY_APPS + 3;
02917 
02918    bytes += adsi_logo(buf + bytes);
02919    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
02920    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
02921    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02922    bytes += adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
02923    bytes += adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
02924    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
02925    bytes += adsi_set_keys(buf + bytes, keys);
02926    bytes += adsi_voice_mode(buf + bytes, 0);
02927    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02928 }

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

Definition at line 2750 of file app_voicemail.c.

References ADSI_COMM_PAGE, adsi_display(), and ADSI_JUST_CENT.

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

02751 {
02752    int bytes = 0;
02753    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
02754    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002 LSS, Inc.", "");
02755    return bytes;
02756 }

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

Definition at line 2981 of file app_voicemail.c.

References adsi_available(), ADSI_KEY_APPS, ADSI_KEY_SKT, ast_strlen_zero(), vm_state::curmsg, vm_state::fn, keys, name, and strsep().

Referenced by play_message(), and vm_execmain().

02982 {
02983    int bytes=0;
02984    unsigned char buf[256]; 
02985    char buf1[256], buf2[256];
02986    char fn2[256];
02987 
02988    char cid[256]="";
02989    char *val;
02990    char *name, *num;
02991    char datetime[21]="";
02992    FILE *f;
02993 
02994    unsigned char keys[8];
02995 
02996    int x;
02997 
02998    if (!adsi_available(chan))
02999       return;
03000 
03001    /* Retrieve important info */
03002    snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
03003    f = fopen(fn2, "r");
03004    if (f) {
03005       while (!feof(f)) {   
03006          fgets((char *)buf, sizeof(buf), f);
03007          if (!feof(f)) {
03008             char *stringp=NULL;
03009             stringp = (char *)buf;
03010             strsep(&stringp, "=");
03011             val = strsep(&stringp, "=");
03012             if (!ast_strlen_zero(val)) {
03013                if (!strcmp((char *)buf, "callerid"))
03014                   ast_copy_string(cid, val, sizeof(cid));
03015                if (!strcmp((char *)buf, "origdate"))
03016                   ast_copy_string(datetime, val, sizeof(datetime));
03017             }
03018          }
03019       }
03020       fclose(f);
03021    }
03022    /* New meaning for keys */
03023    for (x=0;x<5;x++)
03024       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
03025    keys[6] = 0x0;
03026    keys[7] = 0x0;
03027 
03028    if (!vms->curmsg) {
03029       /* No prev key, provide "Folder" instead */
03030       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03031    }
03032    if (vms->curmsg >= vms->lastmsg) {
03033       /* If last message ... */
03034       if (vms->curmsg) {
03035          /* but not only message, provide "Folder" instead */
03036          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03037          bytes += adsi_voice_mode(buf + bytes, 0);
03038 
03039       } else {
03040          /* Otherwise if only message, leave blank */
03041          keys[3] = 1;
03042       }
03043    }
03044 
03045    if (!ast_strlen_zero(cid)) {
03046       ast_callerid_parse(cid, &name, &num);
03047       if (!name)
03048          name = num;
03049    } else
03050       name = "Unknown Caller";
03051 
03052    /* If deleted, show "undeleted" */
03053 
03054    if (vms->deleted[vms->curmsg])
03055       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
03056 
03057    /* Except "Exit" */
03058    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
03059    snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
03060       strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
03061    snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
03062 
03063    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03064    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03065    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
03066    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
03067    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03068    bytes += adsi_set_keys(buf + bytes, keys);
03069    bytes += adsi_voice_mode(buf + bytes, 0);
03070 
03071    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03072 }

static void adsi_password ( struct ast_channel chan  )  [static]

Definition at line 2930 of file app_voicemail.c.

References adsi_available(), ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, adsi_input_control(), adsi_input_format(), ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_MSG_DISPLAY, adsi_set_keys(), adsi_set_line(), adsi_transmit_message(), adsi_voice_mode(), and keys.

Referenced by vm_authenticate().

02931 {
02932    unsigned char buf[256];
02933    int bytes=0;
02934    unsigned char keys[8];
02935    int x;
02936    if (!adsi_available(chan))
02937       return;
02938 
02939    for (x=0;x<8;x++)
02940       keys[x] = 0;
02941    /* Set one key for next */
02942    keys[3] = ADSI_KEY_APPS + 3;
02943 
02944    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02945    bytes += adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
02946    bytes += adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
02947    bytes += adsi_set_keys(buf + bytes, keys);
02948    bytes += adsi_voice_mode(buf + bytes, 0);
02949    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02950 }

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

Definition at line 3119 of file app_voicemail.c.

References adsi_available(), ADSI_COMM_PAGE, adsi_display(), ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, adsi_set_keys(), adsi_set_line(), adsi_transmit_message(), adsi_voice_mode(), keys, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_execmain().

03120 {
03121    unsigned char buf[256] = "";
03122    char buf1[256] = "", buf2[256] = "";
03123    int bytes=0;
03124    unsigned char keys[8];
03125    int x;
03126 
03127    char *newm = (vms->newmessages == 1) ? "message" : "messages";
03128    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
03129    if (!adsi_available(chan))
03130       return;
03131    if (vms->newmessages) {
03132       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
03133       if (vms->oldmessages) {
03134          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
03135          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
03136       } else {
03137          snprintf(buf2, sizeof(buf2), "%s.", newm);
03138       }
03139    } else if (vms->oldmessages) {
03140       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
03141       snprintf(buf2, sizeof(buf2), "%s.", oldm);
03142    } else {
03143       strcpy(buf1, "You have no messages.");
03144       buf2[0] = ' ';
03145       buf2[1] = '\0';
03146    }
03147    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03148    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03149    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03150 
03151    for (x=0;x<6;x++)
03152       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03153    keys[6] = 0;
03154    keys[7] = 0;
03155 
03156    /* Don't let them listen if there are none */
03157    if (vms->lastmsg < 0)
03158       keys[0] = 1;
03159    bytes += adsi_set_keys(buf + bytes, keys);
03160 
03161    bytes += adsi_voice_mode(buf + bytes, 0);
03162 
03163    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03164 }

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

Definition at line 3166 of file app_voicemail.c.

References adsi_available(), ADSI_COMM_PAGE, adsi_display(), ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, adsi_set_keys(), adsi_set_line(), adsi_transmit_message(), adsi_voice_mode(), vm_state::curbox, keys, and vm_state::lastmsg.

Referenced by vm_execmain().

03167 {
03168    unsigned char buf[256] = "";
03169    char buf1[256] = "", buf2[256] = "";
03170    int bytes=0;
03171    unsigned char keys[8];
03172    int x;
03173 
03174    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
03175 
03176    if (!adsi_available(chan))
03177       return;
03178 
03179    /* Original command keys */
03180    for (x=0;x<6;x++)
03181       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03182 
03183    keys[6] = 0;
03184    keys[7] = 0;
03185 
03186    if ((vms->lastmsg + 1) < 1)
03187       keys[0] = 0;
03188 
03189    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
03190       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
03191 
03192    if (vms->lastmsg + 1)
03193       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
03194    else
03195       strcpy(buf2, "no messages.");
03196    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03197    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03198    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
03199    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03200    bytes += adsi_set_keys(buf + bytes, keys);
03201 
03202    bytes += adsi_voice_mode(buf + bytes, 0);
03203 
03204    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03205    
03206 }

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 6493 of file app_voicemail.c.

References ast_callerid_parse(), ast_config_destroy(), ast_config_load(), ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_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, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::fn2, vm_state::heard, leave_voicemail(), LOG_WARNING, make_file(), name, option_verbose, play_message_callerid(), play_message_datetime(), RETRIEVE, vm_state::starting, VERBOSE_PREFIX_3, and wait_file().

Referenced by vm_execmain().

06495 {
06496    int res = 0;
06497    char filename[256],*origtime, *cid, *context, *name, *num;
06498    struct ast_config *msg_cfg;
06499    int retries = 0;
06500 
06501    vms->starting = 0; 
06502    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
06503 
06504    /* Retrieve info from VM attribute file */
06505 
06506    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
06507    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
06508    RETRIEVE(vms->curdir, vms->curmsg);
06509    msg_cfg = ast_config_load(filename);
06510    DISPOSE(vms->curdir, vms->curmsg);
06511    if (!msg_cfg) {
06512       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
06513       return 0;
06514    }
06515 
06516    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
06517       ast_config_destroy(msg_cfg);
06518       return 0;
06519    }
06520 
06521    cid = ast_variable_retrieve(msg_cfg, "message", "callerid");
06522 
06523    context = ast_variable_retrieve(msg_cfg, "message", "context");
06524    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
06525       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
06526 
06527    ast_config_destroy(msg_cfg);
06528 
06529    if (option == 3) {
06530 
06531       if (!res)
06532          res = play_message_datetime(chan, vmu, origtime, filename);
06533       if (!res)
06534          res = play_message_callerid(chan, vms, cid, context, 0);
06535 
06536       res = 't';
06537 
06538    } else if (option == 2) { /* Call back */
06539 
06540       if (!ast_strlen_zero(cid)) {
06541          ast_callerid_parse(cid, &name, &num);
06542          while ((res > -1) && (res != 't')) {
06543             switch(res) {
06544                case '1':
06545                   if (num) {
06546                      /* Dial the CID number */
06547                      res = dialout(chan, vmu, num, vmu->callback);
06548                      if (res)
06549                         return 9;
06550                   } else {
06551                      res = '2';
06552                   }
06553                   break;
06554 
06555                case '2':
06556                   /* Want to enter a different number, can only do this if there's a dialout context for this user */
06557                   if (!ast_strlen_zero(vmu->dialout)) {
06558                      res = dialout(chan, vmu, NULL, vmu->dialout);
06559                      if (res)
06560                         return 9;
06561                   } else {
06562                      if (option_verbose > 2)
06563                         ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
06564                      res = ast_play_and_wait(chan, "vm-sorry");
06565                   }
06566                   return res;
06567                case '*':
06568                   res = 't';
06569                   break;
06570                case '3':
06571                case '4':
06572                case '5':
06573                case '6':
06574                case '7':
06575                case '8':
06576                case '9':
06577                case '0':
06578 
06579                   res = ast_play_and_wait(chan, "vm-sorry");
06580                   retries++;
06581                   break;
06582                default:
06583                   if (num) {
06584                      if (option_verbose > 2)
06585                         ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
06586                      res = ast_play_and_wait(chan, "vm-num-i-have");
06587                      if (!res)
06588                         res = play_message_callerid(chan, vms, num, vmu->context, 1);
06589                      if (!res)
06590                         res = ast_play_and_wait(chan, "vm-tocallnum");
06591                      /* Only prompt for a caller-specified number if there is a dialout context specified */
06592                      if (!ast_strlen_zero(vmu->dialout)) {
06593                         if (!res)
06594                            res = ast_play_and_wait(chan, "vm-calldiffnum");
06595                      }
06596                   } else {
06597                      res = ast_play_and_wait(chan, "vm-nonumber");
06598                      if (!ast_strlen_zero(vmu->dialout)) {
06599                         if (!res)
06600                            res = ast_play_and_wait(chan, "vm-toenternumber");
06601                      }
06602                   }
06603                   if (!res)
06604                      res = ast_play_and_wait(chan, "vm-star-cancel");
06605                   if (!res)
06606                      res = ast_waitfordigit(chan, 6000);
06607                   if (!res) {
06608                      retries++;
06609                      if (retries > 3)
06610                         res = 't';
06611                   }
06612                   break; 
06613                   
06614             }
06615             if (res == 't')
06616                res = 0;
06617             else if (res == '*')
06618                res = -1;
06619          }
06620       }
06621       
06622    }
06623    else if (option == 1) { /* Reply */
06624       /* Send reply directly to sender */
06625       if (!ast_strlen_zero(cid)) {
06626          ast_callerid_parse(cid, &name, &num);
06627          if (!num) {
06628             if (option_verbose > 2)
06629                ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
06630             if (!res)
06631                res = ast_play_and_wait(chan, "vm-nonumber");
06632             return res;
06633          } else {
06634             if (find_user(NULL, vmu->context, num)) {
06635                struct leave_vm_options leave_options;
06636                char mailbox[AST_MAX_EXTENSION * 2 + 2];
06637                snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
06638 
06639                if (option_verbose > 2)
06640                   ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
06641                
06642                memset(&leave_options, 0, sizeof(leave_options));
06643                leave_options.record_gain = record_gain;
06644                res = leave_voicemail(chan, mailbox, &leave_options);
06645                if (!res)
06646                   res = 't';
06647                return res;
06648             } else {
06649                /* Sender has no mailbox, can't reply */
06650                if (option_verbose > 2)
06651                   ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
06652                ast_play_and_wait(chan, "vm-nobox");
06653                res = 't';
06654                return res;
06655             }
06656          } 
06657          res = 0;
06658       }
06659    }
06660 
06661    if (!res) {
06662       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
06663       vms->heard[msg] = 1;
06664       res = wait_file(chan, vms, vms->fn);
06665    }
06666    return res;
06667 }

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

Definition at line 5678 of file app_voicemail.c.

References apply_options(), malloc, ast_vm_user::next, populate_defaults(), s, strsep(), users, and usersl.

Referenced by load_config().

05679 {
05680    /* Assumes lock is already held */
05681    char tmp[256] = "";
05682    char *stringp;
05683    char *s;
05684    struct ast_vm_user *vmu;
05685 
05686    ast_copy_string(tmp, data, sizeof(tmp));
05687    vmu = malloc(sizeof(struct ast_vm_user));
05688    if (vmu) {
05689       memset(vmu, 0, sizeof(struct ast_vm_user));
05690       ast_copy_string(vmu->context, context, sizeof(vmu->context));
05691       ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
05692 
05693       populate_defaults(vmu);
05694 
05695       stringp = tmp;
05696       if ((s = strsep(&stringp, ","))) 
05697          ast_copy_string(vmu->password, s, sizeof(vmu->password));
05698       if (stringp && (s = strsep(&stringp, ","))) 
05699          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
05700       if (stringp && (s = strsep(&stringp, ","))) 
05701          ast_copy_string(vmu->email, s, sizeof(vmu->email));
05702       if (stringp && (s = strsep(&stringp, ","))) 
05703          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
05704       if (stringp && (s = strsep(&stringp, ","))) 
05705          apply_options(vmu, s);
05706       
05707       vmu->next = NULL;
05708       if (usersl)
05709          usersl->next = vmu;
05710       else
05711          users = vmu;
05712       usersl = vmu;
05713    }
05714    return 0;
05715 }

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

Definition at line 441 of file app_voicemail.c.

References apply_options(), ast_log(), ast_set2_flag, ast_true(), 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, and ast_vm_user::zonetag.

Referenced by apply_options(), and find_user_realtime().

00442 {
00443    int x;
00444    if (!strcasecmp(var, "attach")) {
00445       ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 
00446    } else if (!strcasecmp(var, "serveremail")) {
00447       ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail));
00448    } else if (!strcasecmp(var, "language")) {
00449       ast_copy_string(vmu->language, value, sizeof(vmu->language));
00450    } else if (!strcasecmp(var, "tz")) {
00451       ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
00452    } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
00453       ast_set2_flag(vmu, ast_true(value), VM_DELETE); 
00454    } else if (!strcasecmp(var, "saycid")){
00455       ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 
00456    } else if (!strcasecmp(var,"sendvoicemail")){
00457       ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 
00458    } else if (!strcasecmp(var, "review")){
00459       ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 
00460    } else if (!strcasecmp(var, "operator")){
00461       ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);  
00462    } else if (!strcasecmp(var, "envelope")){
00463       ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE);  
00464    } else if (!strcasecmp(var, "sayduration")){
00465       ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION);  
00466    } else if (!strcasecmp(var, "saydurationm")){
00467       if (sscanf(value, "%d", &x) == 1) {
00468          vmu->saydurationm = x;
00469       } else {
00470          ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
00471       }
00472    } else if (!strcasecmp(var, "forcename")){
00473       ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 
00474    } else if (!strcasecmp(var, "forcegreetings")){
00475       ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET);   
00476    } else if (!strcasecmp(var, "callback")) {
00477       ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
00478    } else if (!strcasecmp(var, "dialout")) {
00479       ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout));
00480    } else if (!strcasecmp(var, "exitcontext")) {
00481       ast_copy_string(vmu->exit, value, sizeof(vmu->exit));
00482    } else if (!strcasecmp(var, "maxmsg")) {
00483       vmu->maxmsg = atoi(value);
00484       if (vmu->maxmsg <= 0) {
00485          ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %i\n", value, MAXMSG);
00486          vmu->maxmsg = MAXMSG;
00487       } else if (vmu->maxmsg > MAXMSGLIMIT) {
00488          ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value);
00489          vmu->maxmsg = MAXMSGLIMIT;
00490       }
00491    } else if (!strcasecmp(var, "options")) {
00492       apply_options(vmu, value);
00493    }
00494 }

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

Definition at line 512 of file app_voicemail.c.

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

Referenced by append_mailbox(), and apply_option().

00513 {  /* Destructively Parse options and apply */
00514    char *stringp;
00515    char *s;
00516    char *var, *value;
00517    stringp = ast_strdupa(options);
00518    while ((s = strsep(&stringp, "|"))) {
00519       value = s;
00520       if ((var = strsep(&value, "=")) && value) {
00521          apply_option(vmu, var, value);
00522       }
00523    }  
00524 }

AST_APP_OPTIONS ( vm_app_options   ) 

AST_MUTEX_DEFINE_STATIC ( vmlock   ) 

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

Definition at line 1556 of file app_voicemail.c.

References ast_log(), BASEMAXINLINE, eol, inchar(), LOG_WARNING, n, and ochar().

Referenced by sendmail().

01557 {
01558    unsigned char dtable[BASEMAXINLINE];
01559    int i,hiteof= 0;
01560    FILE *fi;
01561    struct baseio bio;
01562 
01563    memset(&bio, 0, sizeof(bio));
01564    bio.iocp = BASEMAXINLINE;
01565 
01566    if (!(fi = fopen(filename, "rb"))) {
01567       ast_log(LOG_WARNING, "Failed to open log file: %s: %s\n", filename, strerror(errno));
01568       return -1;
01569    }
01570 
01571    for (i= 0;i<9;i++) {
01572       dtable[i]= 'A'+i;
01573       dtable[i+9]= 'J'+i;
01574       dtable[26+i]= 'a'+i;
01575       dtable[26+i+9]= 'j'+i;
01576    }
01577    for (i= 0;i<8;i++) {
01578       dtable[i+18]= 'S'+i;
01579       dtable[26+i+18]= 's'+i;
01580    }
01581    for (i= 0;i<10;i++) {
01582       dtable[52+i]= '0'+i;
01583    }
01584    dtable[62]= '+';
01585    dtable[63]= '/';
01586 
01587    while (!hiteof){
01588       unsigned char igroup[3],ogroup[4];
01589       int c,n;
01590 
01591       igroup[0]= igroup[1]= igroup[2]= 0;
01592 
01593       for (n= 0;n<3;n++) {
01594          if ((c = inchar(&bio, fi)) == EOF) {
01595             hiteof= 1;
01596             break;
01597          }
01598 
01599          igroup[n]= (unsigned char)c;
01600       }
01601 
01602       if (n> 0) {
01603          ogroup[0]= dtable[igroup[0]>>2];
01604          ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)];
01605          ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)];
01606          ogroup[3]= dtable[igroup[2]&0x3F];
01607 
01608          if (n<3) {
01609             ogroup[3]= '=';
01610 
01611             if (n<2)
01612                ogroup[2]= '=';
01613          }
01614 
01615          for (i= 0;i<4;i++)
01616             ochar(&bio, ogroup[i], so);
01617       }
01618    }
01619 
01620    if (fputs(eol,so)==EOF)
01621       return 0;
01622 
01623    fclose(fi);
01624 
01625    return 1;
01626 }

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

Definition at line 496 of file app_voicemail.c.

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

Referenced by vm_change_password().

00497 {
00498    int res;
00499    if (!ast_strlen_zero(vmu->uniqueid)) {
00500       res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL);
00501       if (res > 0) {
00502          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00503          res = 0;
00504       } else if (!res) {
00505          res = -1;
00506       }
00507       return res;
00508    }
00509    return -1;
00510 }

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

Definition at line 3920 of file app_voicemail.c.

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

Referenced by vm_execmain().

03921 {
03922    int x, nummsg;
03923    int res = 0;
03924 
03925    if (vms->lastmsg <= -1)
03926       goto done;
03927 
03928    /* Get the deleted messages fixed */ 
03929    if (vm_lock_path(vms->curdir))
03930       return ERROR_LOCK_PATH;
03931    
03932    vms->curmsg = -1; 
03933    for (x = 0; x < vmu->maxmsg; x++) { 
03934       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
03935          /* Save this message.  It's not in INBOX or hasn't been heard */ 
03936          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
03937          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
03938             break;
03939          vms->curmsg++; 
03940          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
03941          if (strcmp(vms->fn, vms->fn2)) { 
03942             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
03943          } 
03944       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
03945          /* Move to old folder before deleting */ 
03946          res = save_to_folder(vmu, vms->curdir, x, vmu->context, vms->username, 1);
03947          if (res == ERROR_LOCK_PATH) {
03948             /* If save failed do not delete the message */
03949             vms->deleted[x] = 0;
03950             vms->heard[x] = 0;
03951             --x;
03952          } 
03953       } 
03954    } 
03955 
03956    /* Delete ALL remaining messages */
03957    nummsg = x - 1;
03958    for (x = vms->curmsg + 1; x <= nummsg; x++) {
03959       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
03960       if (EXISTS(vms->curdir, x, vms->fn, NULL))
03961          DELETE(vms->curdir, x, vms->fn);
03962    }
03963    ast_unlock_path(vms->curdir);
03964 
03965 done:
03966    if (vms->deleted)
03967       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
03968    if (vms->heard)
03969       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
03970 
03971    return 0;
03972 }

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

Definition at line 5891 of file app_voicemail.c.

References ast_vm_user::context, ast_vm_user::next, strdup, and users.

05892 {
05893    int which = 0;
05894    struct ast_vm_user *vmu = users;
05895    char *context = "";
05896 
05897    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
05898    if (pos > 4)
05899       return NULL;
05900    if (pos == 3) {
05901       if (state == 0)
05902          return strdup("for");
05903       else
05904          return NULL;
05905    }
05906    while (vmu) {
05907       if (!strncasecmp(word, vmu->context, strlen(word))) {
05908          if (context && strcmp(context, vmu->context)) {
05909             if (++which > state) {
05910                return strdup(vmu->context);
05911             }
05912             context = vmu->context;
05913          }
05914       }
05915       vmu = vmu->next;
05916    }
05917    return NULL;
05918 }

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

Definition at line 1408 of file app_voicemail.c.

References ast_log(), LOG_WARNING, and VOICEMAIL_FILE_MODE.

01409 {
01410    int ifd;
01411    int ofd;
01412    int res;
01413    int len;
01414    char buf[4096];
01415 
01416 #ifdef HARDLINK_WHEN_POSSIBLE
01417    /* Hard link if possible; saves disk space & is faster */
01418    if (link(infile, outfile)) {
01419 #endif
01420       if ((ifd = open(infile, O_RDONLY)) < 0) {
01421          ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
01422          return -1;
01423       }
01424       if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
01425          ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
01426          close(ifd);
01427          return -1;
01428       }
01429       do {
01430          len = read(ifd, buf, sizeof(buf));
01431          if (len < 0) {
01432             ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
01433             close(ifd);
01434             close(ofd);
01435             unlink(outfile);
01436          }
01437          if (len) {
01438             res = write(ofd, buf, len);
01439             if (errno == ENOMEM || errno == ENOSPC || res != len) {
01440                ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
01441                close(ifd);
01442                close(ofd);
01443                unlink(outfile);
01444             }
01445          }
01446       } while (len);
01447       close(ifd);
01448       close(ofd);
01449       return 0;
01450 #ifdef HARDLINK_WHEN_POSSIBLE
01451    } else {
01452       /* Hard link succeeded */
01453       return 0;
01454    }
01455 #endif
01456 }

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

Definition at line 1458 of file app_voicemail.c.

References ast_filecopy(), and copy().

01459 {
01460    char frompath2[256],topath2[256];
01461    ast_filecopy(frompath, topath, NULL);
01462    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
01463    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
01464    copy(frompath2, topath2);
01465 }

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

Definition at line 2309 of file app_voicemail.c.

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

Referenced by leave_voicemail().

02310 {
02311    char fromdir[256], todir[256], frompath[256], topath[256];
02312    char *frombox = mbox(imbox);
02313    int recipmsgnum;
02314 
02315    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
02316 
02317    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
02318   
02319    make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
02320    make_file(frompath, sizeof(frompath), fromdir, msgnum);
02321 
02322    if (vm_lock_path(todir))
02323       return ERROR_LOCK_PATH;
02324 
02325    recipmsgnum = 0;
02326    do {
02327       make_file(topath, sizeof(topath), todir, recipmsgnum);
02328       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
02329          break;
02330       recipmsgnum++;
02331    } while (recipmsgnum < recip->maxmsg);
02332    if (recipmsgnum < recip->maxmsg) {
02333       COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
02334    } else {
02335       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
02336    }
02337    ast_unlock_path(todir);
02338    notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
02339    
02340    return 0;
02341 }

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

Definition at line 1375 of file app_voicemail.c.

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

Referenced by forward_message(), leave_voicemail(), and open_mailbox().

01376 {
01377    /* Find all .txt files - even if they are not in sequence from 0000 */
01378 
01379    int vmcount = 0;
01380    DIR *vmdir = NULL;
01381    struct dirent *vment = NULL;
01382 
01383    if (vm_lock_path(dir))
01384       return ERROR_LOCK_PATH;
01385 
01386    if ((vmdir = opendir(dir))) {
01387       while ((vment = readdir(vmdir))) {
01388          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
01389             vmcount++;
01390       }
01391       closedir(vmdir);
01392    }
01393    ast_unlock_path(dir);
01394    
01395    return vmcount;
01396 }

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

basically mkdir -p $dest/$context/$ext/$mailbox String. base directory. String. Ignored if is null or empty string. String. Ignored if is null or empty string. String. Ignored if is null or empty string.

Returns:
0 on failure, 1 on success.

Definition at line 791 of file app_voicemail.c.

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

Referenced by copy_message(), leave_voicemail(), save_to_folder(), and vm_execmain().

00792 {
00793    mode_t   mode = VOICEMAIL_DIR_MODE;
00794 
00795    if(context && context[0] != '\0') {
00796       make_dir(dest, len, context, "", "");
00797       if(mkdir(dest, mode) && errno != EEXIST) {
00798          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00799          return 0;
00800       }
00801    }
00802    if(ext && ext[0] != '\0') {
00803       make_dir(dest, len, context, ext, "");
00804       if(mkdir(dest, mode) && errno != EEXIST) {
00805          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00806          return 0;
00807       }
00808    }
00809    if(mailbox && mailbox[0] != '\0') {
00810       make_dir(dest, len, context, ext, mailbox);
00811       if(mkdir(dest, mode) && errno != EEXIST) {
00812          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00813          return 0;
00814       }
00815    }
00816    return 1;
00817 }

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 6427 of file app_voicemail.c.

06428 {
06429    return tdesc;
06430 }

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

Definition at line 6432 of file app_voicemail.c.

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

Referenced by advanced_options(), and vm_execmain().

06433 {
06434    int cmd = 0;
06435    char destination[80] = "";
06436    int retries = 0;
06437 
06438    if (!num) {
06439       if (option_verbose > 2)
06440          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
06441       while (retries < 3 && cmd != 't') {
06442          destination[1] = '\0';
06443          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
06444          if (!cmd)
06445             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
06446          if (!cmd)
06447             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
06448          if (!cmd) {
06449             cmd = ast_waitfordigit(chan, 6000);
06450             if (cmd)
06451                destination[0] = cmd;
06452          }
06453          if (!cmd) {
06454             retries++;
06455          } else {
06456 
06457             if (cmd < 0)
06458                return 0;
06459             if (cmd == '*') {
06460                if (option_verbose > 2)
06461                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
06462                return 0;
06463             }
06464             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
06465                retries++;
06466             else
06467                cmd = 't';
06468          }
06469       }
06470       if (retries >= 3) {
06471          return 0;
06472       }
06473       
06474    } else {
06475       if (option_verbose > 2)
06476          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
06477       ast_copy_string(destination, num, sizeof(destination));
06478    }
06479 
06480    if (!ast_strlen_zero(destination)) {
06481       if (destination[strlen(destination) -1 ] == '*')
06482          return 0; 
06483       if (option_verbose > 2)
06484          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
06485       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
06486       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
06487       chan->priority = 0;
06488       return 9;
06489    }
06490    return 0;
06491 }

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

Definition at line 577 of file app_voicemail.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_set2_flag, ast_test_flag, find_user_realtime(), globalflags, malloc, ast_vm_user::next, users, VM_ALLOCED, and VM_SEARCH.

00578 {
00579    /* This function could be made to generate one from a database, too */
00580    struct ast_vm_user *vmu=NULL, *cur;
00581    ast_mutex_lock(&vmlock);
00582    cur = users;
00583 
00584    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00585       context = "default";
00586 
00587    while (cur) {
00588       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00589          break;
00590       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00591          break;
00592       cur=cur->next;
00593    }
00594    if (cur) {
00595       if (ivm)
00596          vmu = ivm;
00597       else
00598          /* Make a copy, so that on a reload, we have no race */
00599          vmu = malloc(sizeof(struct ast_vm_user));
00600       if (vmu) {
00601          memcpy(vmu, cur, sizeof(struct ast_vm_user));
00602          ast_set2_flag(vmu, !ivm, VM_ALLOCED);  
00603          vmu->next = NULL;
00604       }
00605    } else
00606       vmu = find_user_realtime(ivm, context, mailbox);
00607    ast_mutex_unlock(&vmlock);
00608    return vmu;
00609 }

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

Definition at line 526 of file app_voicemail.c.

References apply_option(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), free, globalflags, malloc, ast_variable::name, ast_variable::next, populate_defaults(), ast_variable::value, var, VM_ALLOCED, and VM_SEARCH.

Referenced by find_user().

00527 {
00528    struct ast_variable *var, *tmp;
00529    struct ast_vm_user *retval;
00530 
00531    if (ivm)
00532       retval=ivm;
00533    else
00534       retval=malloc(sizeof(struct ast_vm_user));
00535 
00536    if (retval) {
00537       memset(retval, 0, sizeof(struct ast_vm_user));
00538       if (!ivm)
00539          ast_set_flag(retval, VM_ALLOCED);   
00540       if (mailbox) 
00541          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00542       populate_defaults(retval);
00543       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00544          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00545       else
00546          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00547       if (var) {
00548          tmp = var;
00549          while(tmp) {
00550             printf("%s => %s\n", tmp->name, tmp->value);
00551             if (!strcasecmp(tmp->name, "password")) {
00552                ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00553             } else if (!strcasecmp(tmp->name, "uniqueid")) {
00554                ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00555             } else if (!strcasecmp(tmp->name, "pager")) {
00556                ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00557             } else if (!strcasecmp(tmp->name, "email")) {
00558                ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00559             } else if (!strcasecmp(tmp->name, "fullname")) {
00560                ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00561             } else if (!strcasecmp(tmp->name, "context")) {
00562                ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00563             } else
00564                apply_option(retval, tmp->name, tmp->value);
00565             tmp = tmp->next;
00566          } 
00567          ast_variables_destroy(var);
00568       } else { 
00569          if (!ivm) 
00570             free(retval);
00571          retval = NULL;
00572       }  
00573    } 
00574    return retval;
00575 }

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

Definition at line 3378 of file app_voicemail.c.

References app, ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_safe_system(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, count_messages(), ERROR_LOCK_PATH, EVENT_FLAG_CALL, ast_channel::exten, find_user(), free_user(), ast_vm_user::fullname, globalflags, has_voicemail(), ast_channel::language, leave_voicemail(), LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, manager_event(), ast_vm_user::next, pbx_exec(), pbx_findapp(), ast_channel::priority, RETRIEVE, run_externnotify(), s, sendmail(), sendpage(), STORE, strsep(), username, VM_ATTACH, VM_DIRECFORWARD, and vm_forwardoptions().

Referenced by vm_execmain().

03380 {
03381    char username[70]="";
03382    char sys[256];
03383    char todir[256];
03384    int todircount=0;
03385    int duration;
03386    struct ast_config *mif;
03387    char miffile[256];
03388    char fn[256];
03389    char callerid[512];
03390    char ext_context[256]="";
03391    int res = 0, cmd = 0;
03392    struct ast_vm_user *receiver = NULL, *extensions = NULL, *vmtmp = NULL, *vmfree;
03393    char tmp[256];
03394    char *stringp, *s;
03395    int saved_messages = 0, found = 0;
03396    int valid_extensions = 0;
03397    
03398    while (!res && !valid_extensions) {
03399       int use_directory = 0;
03400       if(ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
03401          int done = 0;
03402          int retries = 0;
03403          cmd=0;
03404          while((cmd >= 0) && !done ){
03405             if (cmd)
03406                retries = 0;
03407             switch (cmd) {
03408             case '1': 
03409                use_directory = 0;
03410                done = 1;
03411                break;
03412             case '2': 
03413                use_directory = 1;
03414                done=1;
03415                break;
03416             case '*': 
03417                cmd = 't';
03418                done = 1;
03419                break;
03420             default: 
03421                /* Press 1 to enter an extension press 2 to use the directory */
03422                cmd = ast_play_and_wait(chan,"vm-forward");
03423                if (!cmd)
03424                   cmd = ast_waitfordigit(chan,3000);
03425                if (!cmd)
03426                   retries++;
03427                if (retries > 3)
03428                {
03429                   cmd = 't';
03430                   done = 1;
03431                }
03432                
03433              }
03434          }
03435          if( cmd<0 || cmd=='t' )
03436             break;
03437       }
03438       
03439       if (use_directory) {
03440          /* use app_directory */
03441          
03442          char old_context[sizeof(chan->context)];
03443          char old_exten[sizeof(chan->exten)];
03444          int old_priority;
03445          struct ast_app* app;
03446 
03447          
03448          app = pbx_findapp("Directory");
03449          if (app) {
03450             /* make backup copies */
03451             char vmcontext[256];
03452             memcpy(old_context, chan->context, sizeof(chan->context));
03453             memcpy(old_exten, chan->exten, sizeof(chan->exten));
03454             old_priority = chan->priority;
03455             
03456             /* call the the Directory, changes the channel */
03457             sprintf(vmcontext, "%s||v", context ? context : "default");
03458             res = pbx_exec(chan, app, vmcontext, 1);
03459             
03460             ast_copy_string(username, chan->exten, sizeof(username));
03461             
03462             /* restore the old context, exten, and priority */
03463             memcpy(chan->context, old_context, sizeof(chan->context));
03464             memcpy(chan->exten, old_exten, sizeof(chan->exten));
03465             chan->priority = old_priority;
03466             
03467          } else {
03468             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
03469             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
03470          }
03471       } else   {
03472          /* Ask for an extension */
03473          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
03474          if (res)
03475             break;
03476          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
03477             break;
03478       }
03479       
03480       /* start all over if no username */
03481       if (ast_strlen_zero(username))
03482          continue;
03483       stringp = username;
03484       s = strsep(&stringp, "*");
03485       /* start optimistic */
03486       valid_extensions = 1;
03487       while (s) {
03488          /* Don't forward to ourselves.  find_user is going to malloc since we have a NULL as first argument */
03489          if (strcmp(s,sender->mailbox) && (receiver = find_user(NULL, context, s))) {
03490             if (!extensions)
03491                vmtmp = extensions = receiver;
03492             else {
03493                vmtmp->next = receiver;
03494                vmtmp = receiver;
03495             }
03496             found++;
03497          } else {
03498             valid_extensions = 0;
03499             break;
03500          }
03501          s = strsep(&stringp, "*");
03502       }
03503       /* break from the loop of reading the extensions */
03504       if (valid_extensions)
03505          break;
03506       /* "I am sorry, that's not a valid extension.  Please try again." */
03507       res = ast_play_and_wait(chan, "pbx-invalid");
03508    }
03509    /* check if we're clear to proceed */
03510    if (!extensions || !valid_extensions)
03511       return res;
03512    vmtmp = extensions;
03513    if (flag==1) {
03514       struct leave_vm_options leave_options;
03515       char mailbox[AST_MAX_EXTENSION * 2 + 2];
03516       snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
03517 
03518       /* Send VoiceMail */
03519       memset(&leave_options, 0, sizeof(leave_options));
03520       leave_options.record_gain = record_gain;
03521       cmd = leave_voicemail(chan, mailbox, &leave_options);
03522    } else {
03523       /* Forward VoiceMail */
03524       RETRIEVE(dir, curmsg);
03525       cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, context, record_gain);
03526       if (!cmd) {
03527          while (!res && vmtmp) {
03528             /* if (ast_play_and_wait(chan, "vm-savedto"))
03529                break;
03530             */
03531             snprintf(todir, sizeof(todir), "%s%s/%s/INBOX",  VM_SPOOL_DIR, vmtmp->context, vmtmp->mailbox);
03532             snprintf(sys, sizeof(sys), "mkdir -p %s\n", todir);
03533             snprintf(ext_context, sizeof(ext_context), "%s@%s", vmtmp->mailbox, vmtmp->context);
03534             ast_log(LOG_DEBUG, "%s", sys);
03535             ast_safe_system(sys);
03536       
03537             res = count_messages(receiver, todir);
03538 
03539             if ( (res == ERROR_LOCK_PATH) || (res < 0) ) {
03540                if (res == ERROR_LOCK_PATH)
03541                   ast_log(LOG_WARNING, "Unable to lock the directory %s to forward the requested vmail msg!\n", todir);
03542                else
03543                   ast_log(LOG_WARNING, "Unable to determine how many msgs are in the destination folder!\n");
03544                break;
03545             }
03546             todircount = res;
03547             ast_copy_string(tmp, fmt, sizeof(tmp));
03548             stringp = tmp;
03549             while ((s = strsep(&stringp, "|"))) {
03550                /* XXX This is a hack -- we should use build_filename or similar XXX */
03551                if (!strcasecmp(s, "wav49"))
03552                   s = "WAV";
03553                snprintf(sys, sizeof(sys), "cp %s/msg%04d.%s %s/msg%04d.%s\n", dir, curmsg, s, todir, todircount, s);
03554                ast_log(LOG_DEBUG, "%s", sys);
03555                ast_safe_system(sys);
03556             }
03557             snprintf(sys, sizeof(sys), "cp %s/msg%04d.txt %s/msg%04d.txt\n", dir, curmsg, todir, todircount);
03558             ast_log(LOG_DEBUG, "%s", sys);
03559             ast_safe_system(sys);
03560             snprintf(fn, sizeof(fn), "%s/msg%04d", todir,todircount);
03561 
03562             STORE(todir, vmtmp->mailbox, vmtmp->context, todircount);
03563    
03564             /* load the information on the source message so we can send an e-mail like a new message */
03565             snprintf(miffile, sizeof(miffile), "%s/msg%04d.txt", dir, curmsg);
03566             if ((mif=ast_config_load(miffile))) {
03567    
03568                /* set callerid and duration variables */
03569                snprintf(callerid, sizeof(callerid), "FWD from: %s from %s", sender->fullname, ast_variable_retrieve(mif, NULL, "callerid"));
03570                s = ast_variable_retrieve(mif, NULL, "duration");
03571                if (s)
03572                   duration = atoi(s);
03573                else
03574                   duration = 0;
03575                if (!ast_strlen_zero(vmtmp->email)) {
03576                   int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
03577                   char *myserveremail = serveremail;
03578                   attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
03579                   if (!ast_strlen_zero(vmtmp->serveremail))
03580                      myserveremail = vmtmp->serveremail;
03581                   sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, chan->cid.cid_num, chan->cid.cid_name, fn, tmp, duration, attach_user_voicemail);
03582                }
03583 
03584                if (!ast_strlen_zero(vmtmp->pager)) {
03585                   char *myserveremail = serveremail;
03586                   if (!ast_strlen_zero(vmtmp->serveremail))
03587                      myserveremail = vmtmp->serveremail;
03588                   sendpage(myserveremail, vmtmp->pager, todircount, vmtmp->context, vmtmp->mailbox, chan->cid.cid_num, chan->cid.cid_name, duration, vmtmp);
03589                }
03590               
03591                ast_config_destroy(mif); /* or here */
03592             }
03593             /* Leave voicemail for someone */
03594             manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
03595             run_externnotify(vmtmp->context, vmtmp->mailbox);
03596    
03597             saved_messages++;
03598             vmfree = vmtmp;
03599             vmtmp = vmtmp->next;
03600             free_user(vmfree);
03601          }
03602          if (saved_messages > 0) {
03603             /* give confirmation that the message was saved */
03604             /* commented out since we can't forward batches yet
03605             if (saved_messages == 1)
03606                res = ast_play_and_wait(chan, "vm-message");
03607             else
03608                res = ast_play_and_wait(chan, "vm-messages");
03609             if (!res)
03610                res = ast_play_and_wait(chan, "vm-saved"); */
03611             res = ast_play_and_wait(chan, "vm-msgsaved");
03612          }  
03613       }
03614    }
03615    return res ? res : cmd;
03616 }

static void free_user ( struct ast_vm_user vmu  )  [static]

Definition at line 1971 of file app_voicemail.c.

References ast_test_flag, free, and VM_ALLOCED.

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

01972 {
01973    if (ast_test_flag(vmu, VM_ALLOCED))
01974       free(vmu);
01975 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 1977 of file app_voicemail.c.

References free.

01978 {
01979    free(z);
01980 }

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

Definition at line 1922 of file app_voicemail.c.

References t.

Referenced by leave_voicemail(), and tds_log().

01923 {
01924    struct tm tm;
01925    time_t t;
01926    t = time(0);
01927    localtime_r(&t,&tm);
01928    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
01929 }

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

Definition at line 3242 of file app_voicemail.c.

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

Referenced by get_folder2().

03243 {
03244    int x;
03245    int d;
03246    char fn[256];
03247    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
03248    if (d)
03249       return d;
03250    for (x = start; x< 5; x++) {  /* For all folders */
03251       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
03252          return d;
03253       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
03254       if (d)
03255          return d;
03256       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
03257       d = vm_play_folder_name(chan, fn);
03258       if (d)
03259          return d;
03260       d = ast_waitfordigit(chan, 500);
03261       if (d)
03262          return d;
03263    }
03264    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
03265    if (d)
03266       return d;
03267    d = ast_waitfordigit(chan, 4000);
03268    return d;
03269 }

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

Definition at line 3271 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

03272 {
03273    int res = 0;
03274    res = ast_play_and_wait(chan, fn);  /* Folder name */
03275    while (((res < '0') || (res > '9')) &&
03276          (res != '#') && (res >= 0)) {
03277       res = get_folder(chan, 0);
03278    }
03279    return res;
03280 }

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

Definition at line 5817 of file app_voicemail.c.

References ast_cli(), ast_vm_user::context, ast_vm_user::fullname, ast_vm_user::mailbox, make_dir(), ast_vm_user::next, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, users, and ast_vm_user::zonetag.

05818 {
05819    struct ast_vm_user *vmu = users;
05820    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
05821 
05822    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
05823    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
05824 
05825    if (vmu) {
05826       if (argc == 3)
05827          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
05828       else {
05829          int count = 0;
05830          while (vmu) {
05831             if (!strcmp(argv[4],vmu->context))
05832                count++;
05833             vmu = vmu->next;
05834          }
05835          if (count) {
05836             vmu = users;
05837             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
05838          } else {
05839             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
05840             return RESULT_FAILURE;
05841          }
05842       }
05843       while (vmu) {
05844          char dirname[256];
05845          DIR *vmdir;
05846          struct dirent *vment;
05847          int vmcount = 0;
05848          char count[12];
05849 
05850          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
05851             make_dir(dirname, 255, vmu->context, vmu->mailbox, "INBOX");
05852             if ((vmdir = opendir(dirname))) {
05853                /* No matter what the format of VM, there will always be a .txt file for each message. */
05854                while ((vment = readdir(vmdir)))
05855                   if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7,".txt",4))
05856                      vmcount++;
05857                closedir(vmdir);
05858             }
05859             snprintf(count,sizeof(count),"%d",vmcount);
05860             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
05861          }
05862          vmu = vmu->next;
05863       }
05864    } else {
05865       ast_cli(fd, "There are no voicemail users currently defined\n");
05866       return RESULT_FAILURE;
05867    }
05868    return RESULT_SUCCESS;
05869 }

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

Definition at line 5871 of file app_voicemail.c.

References ast_cli(), vm_zone::msg_format, vm_zone::name, vm_zone::next, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, vm_zone::timezone, and zones.

05872 {
05873    struct vm_zone *zone = zones;
05874    char *output_format = "%-15s %-20s %-45s\n";
05875 
05876    if (argc != 3) return RESULT_SHOWUSAGE;
05877 
05878    if (zone) {
05879       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
05880       while (zone) {
05881          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
05882          zone = zone->next;
05883       }
05884    } else {
05885       ast_cli(fd, "There are no voicemail zones currently defined\n");
05886       return RESULT_FAILURE;
05887    }
05888    return RESULT_SUCCESS;
05889 }

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

Definition at line 2186 of file app_voicemail.c.

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

02187 {
02188    DIR *dir;
02189    struct dirent *de;
02190    char fn[256];
02191    char tmp[256]="";
02192    char *mb, *cur;
02193    char *context;
02194    int ret;
02195    if (!folder)
02196       folder = "INBOX";
02197    /* If no mailbox, return immediately */
02198    if (ast_strlen_zero(mailbox))
02199       return 0;
02200    if (strchr(mailbox, ',')) {
02201       ast_copy_string(tmp, mailbox, sizeof(tmp));
02202       mb = tmp;
02203       ret = 0;
02204       while((cur = strsep(&mb, ","))) {
02205          if (!ast_strlen_zero(cur)) {
02206             if (has_voicemail(cur, folder))
02207                return 1; 
02208          }
02209       }
02210       return 0;
02211    }
02212    ast_copy_string(tmp, mailbox, sizeof(tmp));
02213    context = strchr(tmp, '@');
02214    if (context) {
02215       *context = '\0';
02216       context++;
02217    } else
02218       context = "default";
02219    snprintf(fn, sizeof(fn), "%s/%s/%s/%s", VM_SPOOL_DIR, context, tmp, folder);
02220    dir = opendir(fn);
02221    if (!dir)
02222       return 0;
02223    while ((de = readdir(dir))) {
02224       if (!strncasecmp(de->d_name, "msg", 3))
02225          break;
02226    }
02227    closedir(dir);
02228    if (de)
02229       return 1;
02230    return 0;
02231 }

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

Definition at line 1506 of file app_voicemail.c.

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

Referenced by inchar(), and vm_change_password().

01507 {
01508    int l;
01509 
01510    if (bio->ateof)
01511       return 0;
01512 
01513    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
01514       if (ferror(fi))
01515          return -1;
01516 
01517       bio->ateof = 1;
01518       return 0;
01519    }
01520 
01521    bio->iolen= l;
01522    bio->iocp= 0;
01523 
01524    return 1;
01525 }

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

Definition at line 1528 of file app_voicemail.c.

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

Referenced by base_encode().

01529 {
01530    if (bio->iocp>=bio->iolen) {
01531       if (!inbuf(bio, fi))
01532          return EOF;
01533    }
01534 
01535    return bio->iobuf[bio->iocp++];
01536 }

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

Definition at line 1931 of file app_voicemail.c.

References ast_fileexists(), ast_say_digit_str(), ast_streamfile(), ast_waitstream(), DISPOSE, ast_channel::language, and RETRIEVE.

Referenced by leave_voicemail().

01932 {
01933    int res;
01934    char fn[256];
01935    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext);
01936    RETRIEVE(fn, -1);
01937    if (ast_fileexists(fn, NULL, NULL) > 0) {
01938       res = ast_streamfile(chan, fn, chan->language);
01939       if (res) {
01940          DISPOSE(fn, -1);
01941          return -1;
01942       }
01943       res = ast_waitstream(chan, ecodes);
01944       if (res) {
01945          DISPOSE(fn, -1);
01946          return res;
01947       }
01948    } else {
01949       /* Dispose just in case */
01950       DISPOSE(fn, -1);
01951       res = ast_streamfile(chan, "vm-theperson", chan->language);
01952       if (res)
01953          return -1;
01954       res = ast_waitstream(chan, ecodes);
01955       if (res)
01956          return res;
01957       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
01958       if (res)
01959          return res;
01960    }
01961    if (busy)
01962       res = ast_streamfile(chan, "vm-isonphone", chan->language);
01963    else
01964       res = ast_streamfile(chan, "vm-isunavail", chan->language);
01965    if (res)
01966       return -1;
01967    res = ast_waitstream(chan, ecodes);
01968    return res;
01969 }

char* key ( void   ) 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 6869 of file app_voicemail.c.

References ASTERISK_GPL_KEY.

06870 {
06871    return ASTERISK_GPL_KEY;
06872 }

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

Definition at line 1470 of file app_voicemail.c.

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

Referenced by open_mailbox().

01471 {
01472    int x;
01473    char fn[256];
01474 
01475    if (vm_lock_path(dir))
01476       return ERROR_LOCK_PATH;
01477 
01478    for (x = 0; x < vmu->maxmsg; x++) {
01479       make_file(fn, sizeof(fn), dir, x);
01480       if (ast_fileexists(fn, NULL, NULL) < 1)
01481          break;
01482    }
01483    ast_unlock_path(dir);
01484 
01485    return x - 1;
01486 }

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

Definition at line 2370 of file app_voicemail.c.

References ast_callerid_merge(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_goto_if_exists(), ast_log(), ast_play_and_wait(), ast_set_flag, ast_stopstream(), 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(), DISPOSE, EXISTS, ast_vm_user::exit, exten, ast_channel::exten, find_user(), free_user(), get_date(), INTRO, invent_message(), ast_channel::language, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_channel::name, notify_new_message(), OPT_BUSY_GREETING, OPT_PRIORITY_JUMP, OPT_SILENT, OPT_UNAVAIL_GREETING, option_debug, option_priority_jumping, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, STORE, strsep(), transfer, VERBOSE_PREFIX_3, vm_lock_path(), and VM_OPERATOR.

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

02371 {
02372    char txtfile[256], tmptxtfile[256];
02373    char callerid[256];
02374    FILE *txt;
02375    int res = 0, txtdes;
02376    int msgnum;
02377    int duration = 0;
02378    int ausemacro = 0;
02379    int ousemacro = 0;
02380    int ouseexten = 0;
02381    char date[256];
02382    char dir[256], tmpdir[260];
02383    char fn[256];
02384    char prefile[256]="";
02385    char tempfile[256]="";
02386    char ext_context[256] = "";
02387    char fmt[80];
02388    char *context;
02389    char ecodes[16] = "#";
02390    char tmp[256] = "", *tmpptr;
02391    struct ast_vm_user *vmu;
02392    struct ast_vm_user svm;
02393    char *category = NULL;
02394 
02395    ast_copy_string(tmp, ext, sizeof(tmp));
02396    ext = tmp;
02397    context = strchr(tmp, '@');
02398    if (context) {
02399       *context = '\0';
02400       context++;
02401       tmpptr = strchr(context, '&');
02402    } else {
02403       tmpptr = strchr(ext, '&');
02404    }
02405 
02406    if (tmpptr) {
02407       *tmpptr = '\0';
02408       tmpptr++;
02409    }
02410 
02411    category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
02412 
02413    if (!(vmu = find_user(&svm, context, ext))) {
02414       ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
02415       if (ast_test_flag(options, OPT_PRIORITY_JUMP) || option_priority_jumping)
02416          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
02417       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02418       return res;
02419    }
02420 
02421    /* Setup pre-file if appropriate */
02422    if (strcmp(vmu->context, "default"))
02423       snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
02424    else
02425       ast_copy_string(ext_context, vmu->context, sizeof(ext_context));
02426    if (ast_test_flag(options, OPT_BUSY_GREETING))
02427       snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
02428    else if (ast_test_flag(options, OPT_UNAVAIL_GREETING))
02429       snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
02430    snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
02431    RETRIEVE(tempfile, -1);
02432    if (ast_fileexists(tempfile, NULL, NULL) > 0)
02433       ast_copy_string(prefile, tempfile, sizeof(prefile));
02434    DISPOSE(tempfile, -1);
02435    /* It's easier just to try to make it than to check for its existence */
02436    create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
02437    create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp");
02438 
02439    /* Check current or macro-calling context for special extensions */
02440    if (ast_test_flag(vmu, VM_OPERATOR)) {
02441       if (!ast_strlen_zero(vmu->exit)) {
02442          if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
02443             strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02444             ouseexten = 1;
02445          }
02446       } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
02447          strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02448          ouseexten = 1;
02449       }
02450       else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
02451          strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02452          ousemacro = 1;
02453       }
02454    }
02455 
02456    if (!ast_strlen_zero(vmu->exit)) {
02457       if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
02458          strncat(ecodes, "*", sizeof(ecodes) -  strlen(ecodes) - 1);
02459    } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
02460       strncat(ecodes, "*", sizeof(ecodes) -  strlen(ecodes) - 1);
02461    else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
02462       strncat(ecodes, "*", sizeof(ecodes) -  strlen(ecodes) - 1);
02463       ausemacro = 1;
02464    }
02465 
02466    /* Play the beginning intro if desired */
02467    if (!ast_strlen_zero(prefile)) {
02468       RETRIEVE(prefile, -1);
02469       if (ast_fileexists(prefile, NULL, NULL) > 0) {
02470          if (ast_streamfile(chan, prefile, chan->language) > -1) 
02471             res = ast_waitstream(chan, ecodes);
02472       } else {
02473          ast_log(LOG_DEBUG, "%s doesn't exist, doing what we can\n", prefile);
02474          res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
02475       }
02476       DISPOSE(prefile, -1);
02477       if (res < 0) {
02478          ast_log(LOG_DEBUG, "Hang up during prefile playback\n");
02479          free_user(vmu);
02480          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02481          return -1;
02482       }
02483    }
02484    if (res == '#') {
02485       /* On a '#' we skip the instructions */
02486       ast_set_flag(options, OPT_SILENT);
02487       res = 0;
02488    }
02489    if (!res && !ast_test_flag(options, OPT_SILENT)) {
02490       res = ast_streamfile(chan, INTRO, chan->language);
02491       if (!res)
02492          res = ast_waitstream(chan, ecodes);
02493       if (res == '#') {
02494          ast_set_flag(options, OPT_SILENT);
02495          res = 0;
02496       }
02497    }
02498    if (res > 0)
02499       ast_stopstream(chan);
02500    /* Check for a '*' here in case the caller wants to escape from voicemail to something
02501       other than the operator -- an automated attendant or mailbox login for example */
02502    if (res == '*') {
02503       chan->exten[0] = 'a';
02504       chan->exten[1] = '\0';
02505       if (!ast_strlen_zero(vmu->exit)) {
02506          ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
02507       } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
02508          ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
02509       }
02510       chan->priority = 0;
02511       free_user(vmu);
02512       pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
02513       return 0;
02514    }
02515 
02516    /* Check for a '0' here */
02517    if (res == '0') {
02518    transfer:
02519       if(ouseexten || ousemacro) {
02520          chan->exten[0] = 'o';
02521          chan->exten[1] = '\0';
02522          if (!ast_strlen_zero(vmu->exit)) {
02523             ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
02524          } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
02525             ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
02526          }
02527          ast_play_and_wait(chan, "transfer");
02528          chan->priority = 0;
02529          free_user(vmu);
02530          pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
02531       }
02532       return 0;
02533    }
02534    if (res < 0) {
02535       free_user(vmu);
02536       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02537       return -1;
02538    }
02539    /* The meat of recording the message...  All the announcements and beeps have been played*/
02540    ast_copy_string(fmt, vmfmts, sizeof(fmt));
02541    if (!ast_strlen_zero(fmt)) {
02542       msgnum = 0;
02543 
02544       if (count_messages(vmu, dir) >= vmu->maxmsg) {
02545          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
02546          if (!res)
02547             res = ast_waitstream(chan, "");
02548          ast_log(LOG_WARNING, "No more messages possible\n");
02549          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02550          goto leave_vm_out;
02551       }
02552 
02553       snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
02554       txtdes = mkstemp(tmptxtfile);
02555       if (txtdes < 0) {
02556          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
02557          if (!res)
02558             res = ast_waitstream(chan, "");
02559          ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
02560          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02561          goto leave_vm_out;
02562       }
02563 
02564       /* Now play the beep once we have the message number for our next message. */
02565       if (res >= 0) {
02566          /* Unless we're *really* silent, try to send the beep */
02567          res = ast_streamfile(chan, "beep", chan->language);
02568          if (!res)
02569             res = ast_waitstream(chan, "");
02570       }
02571 
02572       /* Store information */
02573       txt = fdopen(txtdes, "w+");
02574       if (txt) {
02575          get_date(date, sizeof(date));
02576          fprintf(txt, 
02577             ";\n"
02578             "; Message Information file\n"
02579             ";\n"
02580             "[message]\n"
02581             "origmailbox=%s\n"
02582             "context=%s\n"
02583             "macrocontext=%s\n"
02584             "exten=%s\n"
02585             "priority=%d\n"
02586             "callerchan=%s\n"
02587             "callerid=%s\n"
02588             "origdate=%s\n"
02589             "origtime=%ld\n"
02590             "category=%s\n",
02591             ext,
02592             chan->context,
02593             chan->macrocontext, 
02594             chan->exten,
02595             chan->priority,
02596             chan->name,
02597             ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"),
02598             date, (long)time(NULL),
02599             category ? category : ""); 
02600       } else
02601          ast_log(LOG_WARNING, "Error opening text file for output\n");
02602       res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain);
02603 
02604       if (txt) {
02605          if (duration < vmminmessage) {
02606             if (option_verbose > 2) 
02607                ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage);
02608             fclose(txt);
02609             ast_filedelete(tmptxtfile, NULL);
02610             unlink(tmptxtfile);
02611          } else {
02612             fprintf(txt, "duration=%d\n", duration);
02613             fclose(txt);
02614             if (vm_lock_path(dir)) {
02615                ast_log(LOG_ERROR, "Couldn't lock directory %s.  Voicemail will be lost.\n", dir);
02616                /* Delete files */
02617                ast_filedelete(tmptxtfile, NULL);
02618                unlink(tmptxtfile);
02619             } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
02620                if (option_debug) 
02621                   ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
02622                unlink(tmptxtfile);
02623                ast_unlock_path(dir);
02624             } else {
02625                for (;;) {
02626                   make_file(fn, sizeof(fn), dir, msgnum);
02627                   if (!EXISTS(dir, msgnum, fn, NULL))
02628                      break;
02629                   msgnum++;
02630                }
02631 
02632                /* assign a variable with the name of the voicemail file */   
02633                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
02634 
02635                snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
02636                ast_filerename(tmptxtfile, fn, NULL);
02637                rename(tmptxtfile, txtfile);
02638 
02639                ast_unlock_path(dir);
02640 
02641                /* Are there to be more recipients of this message? */
02642                while (tmpptr) {
02643                   struct ast_vm_user recipu, *recip;
02644                   char *exten, *context;
02645 
02646                   exten = strsep(&tmpptr, "&");
02647                   context = strchr(exten, '@');
02648                   if (context) {
02649                      *context = '\0';
02650                      context++;
02651                   }
02652                   if ((recip = find_user(&recipu, context, exten))) {
02653                      copy_message(chan, vmu, 0, msgnum, duration, recip, fmt);
02654                      free_user(recip);
02655                   }
02656                }
02657                if (ast_fileexists(fn, NULL, NULL) > 0) {
02658                   STORE(dir, vmu->mailbox, vmu->context, msgnum);
02659                   notify_new_message(chan, vmu, msgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
02660                   DISPOSE(dir, msgnum);
02661                }
02662             }
02663          }
02664       }
02665 
02666       if (res == '0') {
02667          goto transfer;
02668       } else if (res > 0)
02669          res = 0;
02670 
02671       if (duration < vmminmessage)
02672          /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
02673          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02674       else
02675          pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
02676    } else
02677       ast_log(LOG_WARNING, "No format for saving voicemail?\n");
02678  leave_vm_out:
02679    free_user(vmu);
02680    
02681    return res;
02682 }

static int load_config ( void   )  [static]

Definition at line 5930 of file app_voicemail.c.

References append_mailbox(), ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, cfg, free, free_user(), free_zone(), globalflags, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, malloc, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, vm_zone::msg_format, vm_zone::name, vm_zone::next, ast_vm_user::next, s, SENDMAIL, strdup, strsep(), vm_zone::timezone, users, usersl, 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, VOICEMAIL_CONFIG, zones, and zonesl.

05931 {
05932    struct ast_vm_user *cur, *l;
05933    struct vm_zone *zcur, *zl;
05934    struct ast_config *cfg;
05935    char *cat;
05936    struct ast_variable *var;
05937    char *notifystr = NULL;
05938    char *astattach;
05939    char *astsearch;
05940    char *astsaycid;
05941    char *send_voicemail;
05942    char *astcallop;
05943    char *astreview;
05944    char *astskipcmd;
05945    char *asthearenv;
05946    char *astsaydurationinfo;
05947    char *astsaydurationminfo;
05948    char *silencestr;
05949    char *maxmsgstr;
05950    char *astdirfwd;
05951    char *thresholdstr;
05952    char *fmt;
05953    char *astemail;
05954    char *astmailcmd = SENDMAIL;
05955    char *s,*q,*stringp;
05956    char *dialoutcxt = NULL;
05957    char *callbackcxt = NULL;  
05958    char *exitcxt = NULL;   
05959    char *extpc;
05960    char *emaildateformatstr;
05961    int x;
05962    int tmpadsi[4];
05963 
05964    cfg = ast_config_load(VOICEMAIL_CONFIG);
05965    ast_mutex_lock(&vmlock);
05966    cur = users;
05967    while (cur) {
05968       l = cur;
05969       cur = cur->next;
05970       ast_set_flag(l, VM_ALLOCED);  
05971       free_user(l);
05972    }
05973    zcur = zones;
05974    while (zcur) {
05975       zl = zcur;
05976       zcur = zcur->next;
05977       free_zone(zl);
05978    }
05979    zones = NULL;
05980    zonesl = NULL;
05981    users = NULL;
05982    usersl = NULL;
05983    memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
05984 
05985    if (cfg) {
05986       /* General settings */
05987 
05988       /* Attach voice message to mail message ? */
05989       if (!(astattach = ast_variable_retrieve(cfg, "general", "attach"))) 
05990          astattach = "yes";
05991       ast_set2_flag((&globalflags), ast_true(astattach), VM_ATTACH); 
05992 
05993       if (!(astsearch = ast_variable_retrieve(cfg, "general", "searchcontexts")))
05994          astsearch = "no";
05995       ast_set2_flag((&globalflags), ast_true(astsearch), VM_SEARCH);
05996 
05997 #ifdef USE_ODBC_STORAGE
05998       strcpy(odbc_database, "asterisk");
05999       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
06000          ast_copy_string(odbc_database, thresholdstr, sizeof(odbc_database));
06001       }
06002       strcpy(odbc_table, "voicemessages");
06003                 if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbctable"))) {
06004                         ast_copy_string(odbc_table, thresholdstr, sizeof(odbc_table));
06005                 }
06006 #endif      
06007       /* Mail command */
06008       strcpy(mailcmd, SENDMAIL);
06009       if ((astmailcmd = ast_variable_retrieve(cfg, "general", "mailcmd")))
06010          ast_copy_string(mailcmd, astmailcmd, sizeof(mailcmd)); /* User setting */
06011 
06012       maxsilence = 0;
06013       if ((silencestr = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
06014          maxsilence = atoi(silencestr);
06015          if (maxsilence > 0)
06016             maxsilence *= 1000;
06017       }
06018       
06019       if (!(maxmsgstr = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
06020          maxmsg = MAXMSG;
06021       } else {
06022          maxmsg = atoi(maxmsgstr);
06023          if (maxmsg <= 0) {
06024             ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", maxmsgstr, MAXMSG);
06025             maxmsg = MAXMSG;
06026          } else if (maxmsg > MAXMSGLIMIT) {
06027             ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, maxmsgstr);
06028             maxmsg = MAXMSGLIMIT;
06029          }
06030       }
06031 
06032       /* Load date format config for voicemail mail */
06033       if ((emaildateformatstr = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
06034          ast_copy_string(emaildateformat, emaildateformatstr, sizeof(emaildateformat));
06035       }
06036 
06037       /* External password changing command */
06038       if ((extpc = ast_variable_retrieve(cfg, "general", "externpass"))) {
06039          ast_copy_string(ext_pass_cmd,extpc,sizeof(ext_pass_cmd));
06040       }
06041 
06042       /* External voicemail notify application */
06043       
06044       if ((notifystr = ast_variable_retrieve(cfg, "general", "externnotify"))) {
06045          ast_copy_string(externnotify, notifystr, sizeof(externnotify));
06046          ast_log(LOG_DEBUG, "found externnotify: %s\n", externnotify);
06047       } else {
06048          externnotify[0] = '\0';
06049       }
06050 
06051       /* Silence treshold */
06052       silencethreshold = 256;
06053       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "silencethreshold")))
06054          silencethreshold = atoi(thresholdstr);
06055       
06056       if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail"))) 
06057          astemail = ASTERISK_USERNAME;
06058       ast_copy_string(serveremail, astemail, sizeof(serveremail));
06059       
06060       vmmaxmessage = 0;
06061       if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
06062          if (sscanf(s, "%d", &x) == 1) {
06063             vmmaxmessage = x;
06064          } else {
06065             ast_log(LOG_WARNING, "Invalid max message time length\n");
06066          }
06067       }
06068 
06069       vmminmessage = 0;
06070       if ((s = ast_variable_retrieve(cfg, "general", "minmessage"))) {
06071          if (sscanf(s, "%d", &x) == 1) {
06072             vmminmessage = x;
06073             if (maxsilence <= vmminmessage)
06074                ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
06075          } else {
06076             ast_log(LOG_WARNING, "Invalid min message time length\n");
06077          }
06078       }
06079       fmt = ast_variable_retrieve(cfg, "general", "format");
06080       if (!fmt)
06081          fmt = "wav";   
06082       ast_copy_string(vmfmts, fmt, sizeof(vmfmts));
06083 
06084       skipms = 3000;
06085       if ((s = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
06086          if (sscanf(s, "%d", &x) == 1) {
06087             maxgreet = x;
06088          } else {
06089             ast_log(LOG_WARNING, "Invalid max message greeting length\n");
06090          }
06091       }
06092 
06093       if ((s = ast_variable_retrieve(cfg, "general", "skipms"))) {
06094          if (sscanf(s, "%d", &x) == 1) {
06095             skipms = x;
06096          } else {
06097             ast_log(LOG_WARNING, "Invalid skipms value\n");
06098          }
06099       }
06100 
06101       maxlogins = 3;
06102       if ((s = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
06103          if (sscanf(s, "%d", &x) == 1) {
06104             maxlogins = x;
06105          } else {
06106             ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
06107          }
06108       }
06109 
06110       /* Force new user to record name ? */
06111       if (!(astattach = ast_variable_retrieve(cfg, "general", "forcename"))) 
06112          astattach = "no";
06113       ast_set2_flag((&globalflags), ast_true(astattach), VM_FORCENAME);
06114 
06115       /* Force new user to record greetings ? */
06116       if (!(astattach = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 
06117          astattach = "no";
06118       ast_set2_flag((&globalflags), ast_true(astattach), VM_FORCEGREET);
06119 
06120       if ((s = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))){
06121          ast_log(LOG_DEBUG,"VM_CID Internal context string: %s\n",s);
06122          stringp = ast_strdupa(s);
06123          for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
06124             if (!ast_strlen_zero(stringp)) {
06125                q = strsep(&stringp,",");
06126                while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
06127                   q++;
06128                ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
06129                ast_log(LOG_DEBUG,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
06130             } else {
06131                cidinternalcontexts[x][0] = '\0';
06132             }
06133          }
06134       }
06135       if (!(astreview = ast_variable_retrieve(cfg, "general", "review"))){
06136          ast_log(LOG_DEBUG,"VM Review Option disabled globally\n");
06137          astreview = "no";
06138       }
06139       ast_set2_flag((&globalflags), ast_true(astreview), VM_REVIEW); 
06140 
06141       if (!(astcallop = ast_variable_retrieve(cfg, "general", "operator"))){
06142          ast_log(LOG_DEBUG,"VM Operator break disabled globally\n");
06143          astcallop = "no";
06144       }
06145       ast_set2_flag((&globalflags), ast_true(astcallop), VM_OPERATOR);  
06146 
06147       if (!(astsaycid = ast_variable_retrieve(cfg, "general", "saycid"))) {
06148          ast_log(LOG_DEBUG,"VM CID Info before msg disabled globally\n");
06149          astsaycid = "no";
06150       } 
06151       ast_set2_flag((&globalflags), ast_true(astsaycid), VM_SAYCID); 
06152 
06153       if (!(send_voicemail = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){
06154          ast_log(LOG_DEBUG,"Send Voicemail msg disabled globally\n");
06155          send_voicemail = "no";
06156       }
06157       ast_set2_flag((&globalflags), ast_true(send_voicemail), VM_SVMAIL);
06158    
06159       if (!(asthearenv = ast_variable_retrieve(cfg, "general", "envelope"))) {
06160          ast_log(LOG_DEBUG,"ENVELOPE before msg enabled globally\n");
06161          asthearenv = "yes";
06162       }
06163       ast_set2_flag((&globalflags), ast_true(asthearenv), VM_ENVELOPE); 
06164 
06165       if (!(astsaydurationinfo = ast_variable_retrieve(cfg, "general", "sayduration"))) {
06166          ast_log(LOG_DEBUG,"Duration info before msg enabled globally\n");
06167          astsaydurationinfo = "yes";
06168       }
06169       ast_set2_flag((&globalflags), ast_true(astsaydurationinfo), VM_SAYDURATION);  
06170 
06171       saydurationminfo = 2;
06172       if ((astsaydurationminfo = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
06173          if (sscanf(astsaydurationminfo, "%d", &x) == 1) {
06174             saydurationminfo = x;
06175          } else {
06176             ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
06177          }
06178       }
06179 
06180       if (!(astskipcmd = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
06181          ast_log(LOG_DEBUG,"We are not going to skip to the next msg after save/delete\n");
06182          astskipcmd = "no";
06183       }
06184       ast_set2_flag((&globalflags), ast_true(astskipcmd), VM_SKIPAFTERCMD);
06185 
06186       if ((dialoutcxt = ast_variable_retrieve(cfg, "general", "dialout"))) {
06187          ast_copy_string(dialcontext, dialoutcxt, sizeof(dialcontext));
06188          ast_log(LOG_DEBUG, "found dialout context: %s\n", dialcontext);
06189       } else {
06190          dialcontext[0] = '\0';  
06191       }
06192       
06193       if ((callbackcxt = ast_variable_retrieve(cfg, "general", "callback"))) {
06194          ast_copy_string(callcontext, callbackcxt, sizeof(callcontext));
06195          ast_log(LOG_DEBUG, "found callback context: %s\n", callcontext);
06196       } else {
06197          callcontext[0] = '\0';
06198       }
06199 
06200       if ((exitcxt = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
06201          ast_copy_string(exitcontext, exitcxt, sizeof(exitcontext));
06202          ast_log(LOG_DEBUG, "found operator context: %s\n", exitcontext);
06203       } else {
06204          exitcontext[0] = '\0';
06205       }
06206 
06207       if (!(astdirfwd = ast_variable_retrieve(cfg, "general", "usedirectory"))) 
06208          astdirfwd = "no";
06209       ast_set2_flag((&globalflags), ast_true(astdirfwd), VM_DIRECFORWARD); 
06210       cat = ast_category_browse(cfg, NULL);
06211       while (cat) {
06212          if (strcasecmp(cat, "general")) {
06213             var = ast_variable_browse(cfg, cat);
06214             if (strcasecmp(cat, "zonemessages")) {
06215                /* Process mailboxes in this context */
06216                while (var) {
06217                   append_mailbox(cat, var->name, var->value);
06218                   var = var->next;
06219                }
06220             } else {
06221                /* Timezones in this context */
06222                while (var) {
06223                   struct vm_zone *z;
06224                   z = malloc(sizeof(struct vm_zone));
06225                   if (z != NULL) {
06226                      char *msg_format, *timezone;
06227                      msg_format = ast_strdupa(var->value);
06228                      if (msg_format != NULL) {
06229                         timezone = strsep(&msg_format, "|");
06230                         if (msg_format) {
06231                            ast_copy_string(z->name, var->name, sizeof(z->name));
06232                            ast_copy_string(z->timezone, timezone, sizeof(z->timezone));
06233                            ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
06234                            z->next = NULL;
06235                            if (zones) {
06236                               zonesl->next = z;
06237                               zonesl = z;
06238                            } else {
06239                               zones = z;
06240                               zonesl = z;
06241                            }
06242                         } else {
06243                            ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
06244                            free(z);
06245                         }
06246                      } else {
06247                         ast_log(LOG_WARNING, "Out of memory while reading voicemail config\n");
06248                         free(z);
06249                         ast_mutex_unlock(&vmlock);
06250                         ast_config_destroy(cfg);
06251                         return -1;
06252                      }
06253                   } else {
06254                      ast_log(LOG_WARNING, "Out of memory while reading voicemail config\n");
06255                      ast_mutex_unlock(&vmlock);
06256                      ast_config_destroy(cfg);
06257                      return -1;
06258                   }
06259                   var = var->next;
06260                }
06261             }
06262          }
06263          cat = ast_category_browse(cfg, cat);
06264       }
06265       memset(fromstring,0,sizeof(fromstring));
06266       memset(pagerfromstring,0,sizeof(pagerfromstring));
06267       memset(emailtitle,0,sizeof(emailtitle));
06268       strcpy(charset, "ISO-8859-1");
06269       if (emailbody) {
06270          free(emailbody);
06271          emailbody = NULL;
06272       }
06273       if (emailsubject) {
06274          free(emailsubject);
06275          emailsubject = NULL;
06276       }
06277                if (pagerbody) {
06278                        free(pagerbody);
06279                        pagerbody = NULL;
06280                }
06281                if (pagersubject) {
06282                        free(pagersubject);
06283                        pagersubject = NULL;
06284                }
06285       if ((s=ast_variable_retrieve(cfg, "general", "pbxskip")))
06286          ast_set2_flag((&globalflags), ast_true(s), VM_PBXSKIP);
06287       if ((s=ast_variable_retrieve(cfg, "general", "fromstring")))
06288          ast_copy_string(fromstring,s,sizeof(fromstring));
06289       if ((s=ast_variable_retrieve(cfg, "general", "pagerfromstring")))
06290          ast_copy_string(pagerfromstring,s,sizeof(pagerfromstring));
06291       if ((s=ast_variable_retrieve(cfg, "general", "charset")))
06292          ast_copy_string(charset,s,sizeof(charset));
06293       if ((s=ast_variable_retrieve(cfg, "general", "adsifdn"))) {
06294          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
06295          for (x=0; x<4; x++) {
06296             memcpy(&adsifdn[x], &tmpadsi[x], 1);
06297          }
06298       }
06299       if ((s=ast_variable_retrieve(cfg, "general", "adsisec"))) {
06300          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
06301          for (x=0; x<4; x++) {
06302             memcpy(&adsisec[x], &tmpadsi[x], 1);
06303          }
06304       }
06305       if ((s=ast_variable_retrieve(cfg, "general", "adsiver")))
06306          if (atoi(s)) {
06307             adsiver = atoi(s);
06308          }
06309       if ((s=ast_variable_retrieve(cfg, "general", "emailtitle"))) {
06310          ast_log(LOG_NOTICE, "Keyword 'emailtitle' is DEPRECATED, please use 'emailsubject' instead.\n");
06311          ast_copy_string(emailtitle,s,sizeof(emailtitle));
06312       }
06313       if ((s=ast_variable_retrieve(cfg, "general", "emailsubject")))
06314          emailsubject = strdup(s);
06315       if ((s=ast_variable_retrieve(cfg, "general", "emailbody"))) {
06316          char *tmpread, *tmpwrite;
06317          emailbody = strdup(s);
06318 
06319          /* substitute strings \t and \n into the apropriate characters */
06320          tmpread = tmpwrite = emailbody;
06321                        while ((tmpwrite = strchr(tmpread,'\\'))) {
06322                                int len = strlen("\n");
06323                                switch (tmpwrite[1]) {
06324                                        case 'n':
06325                                                strncpy(tmpwrite+len,tmpwrite+2,strlen(tmpwrite+2)+1);
06326                                                strncpy(tmpwrite,"\n",len);
06327                                                break;
06328                                        case 't':
06329                                                strncpy(tmpwrite+len,tmpwrite+2,strlen(tmpwrite+2)+1);
06330                                                strncpy(tmpwrite,"\t",len);
06331                                                break;
06332                                        default:
06333                                                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n",tmpwrite[1]);
06334                                }
06335                                tmpread = tmpwrite+len;
06336                        }
06337                }
06338                if ((s=ast_variable_retrieve(cfg, "general", "pagersubject")))
06339                        pagersubject = strdup(s);
06340                if ((s=ast_variable_retrieve(cfg, "general", "pagerbody"))) {
06341                        char *tmpread, *tmpwrite;
06342                        pagerbody = strdup(s);
06343 
06344                        /* substitute strings \t and \n into the apropriate characters */
06345                        tmpread = tmpwrite = pagerbody;
06346          while ((tmpwrite = strchr(tmpread,'\\'))) {
06347             int len = strlen("\n");
06348             switch (tmpwrite[1]) {
06349                case 'n':
06350                   strncpy(tmpwrite+len,tmpwrite+2,strlen(tmpwrite+2)+1);
06351                   strncpy(tmpwrite,"\n",len);
06352                   break;
06353                case 't':
06354                   strncpy(tmpwrite+len,tmpwrite+2,strlen(tmpwrite+2)+1);
06355                   strncpy(tmpwrite,"\t",len);
06356                   break;
06357                default:
06358                   ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n",tmpwrite[1]);
06359             }
06360             tmpread = tmpwrite+len;
06361          }
06362       }
06363       ast_mutex_unlock(&vmlock);
06364       ast_config_destroy(cfg);
06365       return 0;
06366    } else {
06367       ast_mutex_unlock(&vmlock);
06368       ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
06369       return 0;
06370    }
06371 }

int load_module ( void   ) 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 6395 of file app_voicemail.c.

References ast_cli_register(), ast_config_AST_SPOOL_DIR, ast_install_vm_functions(), ast_log(), ast_register_application(), has_voicemail(), load_config(), LOG_WARNING, messagecount(), show_voicemail_users_cli, show_voicemail_zones_cli, vm_box_exists(), vm_exec(), vm_execmain(), and vmauthenticate().

06396 {
06397    int res;
06398    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
06399    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
06400    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
06401    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
06402    if (res)
06403       return(res);
06404 
06405    if ((res=load_config())) {
06406       return(res);
06407    }
06408 
06409    ast_cli_register(&show_voicemail_users_cli);
06410    ast_cli_register(&show_voicemail_zones_cli);
06411 
06412    /* compute the location of the voicemail spool directory */
06413    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
06414 
06415    ast_install_vm_functions(has_voicemail, messagecount);
06416 
06417 #if defined(USE_ODBC_STORAGE) && !defined(EXTENDED_ODBC_STORAGE)
06418    ast_log(LOG_WARNING, "The current ODBC storage table format will be changed soon."
06419             "Please update your tables as per the README and edit the apps/Makefile "
06420             "and uncomment the line containing EXTENDED_ODBC_STORAGE to enable the "
06421             "new table format.\n");
06422 #endif
06423 
06424    return res;
06425 }

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

Definition at line 774 of file app_voicemail.c.

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

00775 {
00776    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, mailbox);
00777 }

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

Definition at line 779 of file app_voicemail.c.

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

00780 {
00781    return snprintf(dest, len, "%s/msg%04d", dir, num);
00782 }

static char* mbox ( int  id  )  [static]

Definition at line 1982 of file app_voicemail.c.

Referenced by adsi_load_vmail(), copy_message(), get_folder(), open_mailbox(), save_to_folder(), vm_box_exists(), and vm_execmain().

01983 {
01984    switch(id) {
01985    case 0:
01986       return "INBOX";
01987    case 1:
01988       return "Old";
01989    case 2:
01990       return "Work";
01991    case 3:
01992       return "Family";
01993    case 4:
01994       return "Friends";
01995    case 5:
01996       return "Cust1";
01997    case 6:
01998       return "Cust2";
01999    case 7:
02000       return "Cust3";
02001    case 8:
02002       return "Cust4";
02003    case 9:
02004       return "Cust5";
02005    default:
02006       return "Unknown";
02007    }
02008 }

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

Definition at line 2234 of file app_voicemail.c.

References ast_strlen_zero(), and strsep().

Referenced by load_module(), and run_externnotify().

02235 {
02236    DIR *dir;
02237    struct dirent *de;
02238    char fn[256];
02239    char tmp[256]="";
02240    char *mb, *cur;
02241    char *context;
02242    int ret;
02243    if (newmsgs)
02244       *newmsgs = 0;
02245    if (oldmsgs)
02246       *oldmsgs = 0;
02247    /* If no mailbox, return immediately */
02248    if (ast_strlen_zero(mailbox))
02249       return 0;
02250    if (strchr(mailbox, ',')) {
02251       int tmpnew, tmpold;
02252       ast_copy_string(tmp, mailbox, sizeof(tmp));
02253       mb = tmp;
02254       ret = 0;
02255       while((cur = strsep(&mb, ", "))) {
02256          if (!ast_strlen_zero(cur)) {
02257             if (messagecount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
02258                return -1;
02259             else {
02260                if (newmsgs)
02261                   *newmsgs += tmpnew; 
02262                if (oldmsgs)
02263                   *oldmsgs += tmpold;
02264             }
02265          }
02266       }
02267       return 0;
02268    }
02269    ast_copy_string(tmp, mailbox, sizeof(tmp));
02270    context = strchr(tmp, '@');
02271    if (context) {
02272       *context = '\0';
02273       context++;
02274    } else
02275       context = "default";
02276    if (newmsgs) {
02277       snprintf(fn, sizeof(fn), "%s/%s/%s/INBOX", VM_SPOOL_DIR, context, tmp);
02278       dir = opendir(fn);
02279       if (dir) {
02280          while ((de = readdir(dir))) {
02281             if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) &&
02282                !strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt"))
02283                   (*newmsgs)++;
02284                
02285          }
02286          closedir(dir);
02287       }
02288    }
02289    if (oldmsgs) {
02290       snprintf(fn, sizeof(fn), "%s/%s/%s/Old", VM_SPOOL_DIR, context, tmp);
02291       dir = opendir(fn);
02292       if (dir) {
02293          while ((de = readdir(dir))) {
02294             if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) &&
02295                !strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt"))
02296                   (*oldmsgs)++;
02297                
02298          }
02299          closedir(dir);
02300       }
02301    }
02302    return 0;
02303 }

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 3331 of file app_voicemail.c.

References ast_app_has_voicemail(), ast_app_messagecount(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::context, DELETE, ast_vm_user::email, EVENT_FLAG_CALL, globalflags, LOG_ERROR, ast_vm_user::mailbox, make_dir(), make_file(), manager_event(), ast_vm_user::pager, run_externnotify(), sendmail(), sendpage(), ast_vm_user::serveremail, strsep(), VM_ATTACH, and VM_DELETE.

Referenced by copy_message(), and leave_voicemail().

03332 {
03333    char todir[256], fn[256], ext_context[256], *stringp;
03334    int newmsgs = 0, oldmsgs = 0;
03335 
03336    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
03337    make_file(fn, sizeof(fn), todir, msgnum);
03338    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
03339 
03340    /* Attach only the first format */
03341    fmt = ast_strdupa(fmt);
03342    if (fmt) {
03343       stringp = fmt;
03344       strsep(&stringp, "|");
03345 
03346       if (!ast_strlen_zero(vmu->email)) {
03347          int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
03348          char *myserveremail = serveremail;
03349          attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
03350          if (!ast_strlen_zero(vmu->serveremail))
03351             myserveremail = vmu->serveremail;
03352          sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail);
03353       }
03354 
03355       if (!ast_strlen_zero(vmu->pager)) {
03356          char *myserveremail = serveremail;
03357          if (!ast_strlen_zero(vmu->serveremail))
03358             myserveremail = vmu->serveremail;
03359          sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu);
03360       }
03361    } else {
03362       ast_log(LOG_ERROR, "Out of memory\n");
03363    }
03364 
03365    if (ast_test_flag(vmu, VM_DELETE)) {
03366       DELETE(todir, msgnum, fn);
03367    }
03368 
03369    /* Leave voicemail for someone */
03370    if (ast_app_has_voicemail(ext_context, NULL)) {
03371       ast_app_messagecount(ext_context, &newmsgs, &oldmsgs);
03372    }
03373    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);
03374    run_externnotify(vmu->context, vmu->mailbox);
03375    return 0;
03376 }

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

Definition at line 1539 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

01540 {
01541    if (bio->linelength>=BASELINELEN) {
01542       if (fputs(eol,so)==EOF)
01543          return -1;
01544 
01545       bio->linelength= 0;
01546    }
01547 
01548    if (putc(((unsigned char)c),so)==EOF)
01549       return -1;
01550 
01551    bio->linelength++;
01552 
01553    return 1;
01554 }

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

Definition at line 3880 of file app_voicemail.c.

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

Referenced by vm_execmain().

03881 {
03882    int res = 0;
03883    int count_msg, last_msg;
03884 
03885    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
03886    
03887    /* Rename the member vmbox HERE so that we don't try to return before
03888     * we know what's going on.
03889     */
03890    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
03891    
03892    make_dir(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
03893    count_msg = count_messages(vmu, vms->curdir);
03894    if (count_msg < 0)
03895       return count_msg;
03896    else
03897       vms->lastmsg = count_msg - 1;
03898 
03899    /*
03900    The following test is needed in case sequencing gets messed up.
03901    There appears to be more than one way to mess up sequence, so
03902    we will not try to find all of the root causes--just fix it when
03903    detected.
03904    */
03905 
03906    last_msg = last_message_index(vmu, vms->curdir);
03907    if (last_msg < 0)
03908       return last_msg;
03909    else if(vms->lastmsg != last_msg)
03910    {
03911       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
03912       res = resequence_mailbox(vmu, vms->curdir);
03913       if (res)
03914          return res;
03915    }
03916 
03917    return 0;
03918 }

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

Definition at line 3806 of file app_voicemail.c.

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

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

03807 {
03808    int res = 0;
03809    char filename[256],*origtime, *cid, *context, *duration;
03810    char *category;
03811    struct ast_config *msg_cfg;
03812 
03813    vms->starting = 0; 
03814    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
03815    adsi_message(chan, vms);
03816    if (!vms->curmsg)
03817       res = wait_file2(chan, vms, "vm-first");  /* "First" */
03818    else if (vms->curmsg == vms->lastmsg)
03819       res = wait_file2(chan, vms, "vm-last");      /* "last" */
03820    if (!res) {
03821                if (!strcasecmp(chan->language, "se")) {             /* SWEDISH syntax */
03822                        res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
03823                }
03824                else {
03825                        res = wait_file2(chan, vms, "vm-message");      /* "message" */
03826                }
03827       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
03828          if (!res)
03829             res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
03830       }
03831    }
03832 
03833    /* Retrieve info from VM attribute file */
03834    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
03835    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
03836    RETRIEVE(vms->curdir, vms->curmsg);
03837    msg_cfg = ast_config_load(filename);
03838    if (!msg_cfg) {
03839       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
03840       return 0;
03841    }
03842                                                                            
03843    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
03844       ast_log(LOG_WARNING, "No origtime?!\n");
03845       DISPOSE(vms->curdir, vms->curmsg);
03846       ast_config_destroy(msg_cfg);
03847       return 0;
03848    }
03849 
03850    cid = ast_variable_retrieve(msg_cfg, "message", "callerid");
03851    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
03852    category = ast_variable_retrieve(msg_cfg, "message", "category");
03853 
03854    context = ast_variable_retrieve(msg_cfg, "message", "context");
03855    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
03856       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
03857 
03858    if (!res)
03859       res = play_message_category(chan, category);
03860    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
03861       res = play_message_datetime(chan, vmu, origtime, filename);
03862    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
03863       res = play_message_callerid(chan, vms, cid, context, 0);
03864         if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
03865                 res = play_message_duration(chan, vms, duration, vmu->saydurationm);
03866    /* Allow pressing '1' to skip envelope / callerid */
03867    if (res == '1')
03868       res = 0;
03869    ast_config_destroy(msg_cfg);
03870 
03871    if (!res) {
03872       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
03873       vms->heard[vms->curmsg] = 1;
03874       res = wait_file(chan, vms, vms->fn);
03875    }
03876    DISPOSE(vms->curdir, vms->curmsg);
03877    return res;
03878 }

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

Definition at line 3720 of file app_voicemail.c.

References ast_callerid_parse(), AST_DIGIT_ANY, ast_fileexists(), ast_log(), ast_say_digit_str(), ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitstream(), ast_channel::language, LOG_DEBUG, MAX_NUM_CID_CONTEXTS, name, option_verbose, VERBOSE_PREFIX_3, and wait_file2().

Referenced by advanced_options(), and play_message().

03721 {
03722    int res = 0;
03723    int i;
03724    char *callerid, *name;
03725    char prefile[256]="";
03726    
03727 
03728    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
03729    /* 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 */
03730    if ((cid == NULL)||(context == NULL))
03731       return res;
03732 
03733    /* Strip off caller ID number from name */
03734    ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
03735    ast_callerid_parse(cid, &name, &callerid);
03736    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
03737       /* Check for internal contexts and only */
03738       /* say extension when the call didn't come from an internal context in the list */
03739       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
03740          ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
03741          if ((strcmp(cidinternalcontexts[i], context) == 0))
03742             break;
03743       }
03744       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
03745          if (!res) {
03746             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
03747             if (!ast_strlen_zero(prefile)) {
03748             /* See if we can find a recorded name for this person instead of their extension number */
03749                if (ast_fileexists(prefile, NULL, NULL) > 0) {
03750                   if (option_verbose > 2)
03751                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
03752                   if (!callback)
03753                      res = wait_file2(chan, vms, "vm-from");
03754                   res = ast_streamfile(chan, prefile, chan->language) > -1;
03755                   res = ast_waitstream(chan, "");
03756                } else {
03757                   if (option_verbose > 2)
03758                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
03759                   /* BB: Say "from extension" as one saying to sound smoother */
03760                   if (!callback)
03761                      res = wait_file2(chan, vms, "vm-from-extension");
03762                   res = ast_say_digit_str(chan, callerid, "", chan->language);
03763                }
03764             }
03765          }
03766       }
03767 
03768       else if (!res){
03769          ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
03770          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
03771          if (!callback)
03772             res = wait_file2(chan, vms, "vm-from-phonenumber");
03773          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
03774       }
03775    } else {
03776       /* Number unknown */
03777       ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
03778       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
03779       res = wait_file2(chan, vms, "vm-unknown-caller");
03780    }
03781    return res;
03782 }

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

Definition at line 3633 of file app_voicemail.c.

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

Referenced by play_message().

03634 {
03635    int res = 0;
03636 
03637    if (!ast_strlen_zero(category))
03638       res = ast_play_and_wait(chan, category);
03639 
03640    if (res) {
03641       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
03642       res = 0;
03643    }
03644 
03645    return res;
03646 }

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

Definition at line 3648 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_log(), ast_say_date_with_format(), ast_strlen_zero(), ast_channel::language, LOG_WARNING, vm_zone::msg_format, vm_zone::name, vm_zone::next, pbx_builtin_setvar_helper(), t, vm_zone::timezone, zones, and ast_vm_user::zonetag.

Referenced by advanced_options(), and play_message().

03649 {
03650    int res = 0;
03651    struct vm_zone *the_zone = NULL;
03652    time_t t;
03653    long tin;
03654 
03655    if (sscanf(origtime,"%ld",&tin) < 1) {
03656       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
03657       return 0;
03658    }
03659    t = tin;
03660 
03661    /* Does this user have a timezone specified? */
03662    if (!ast_strlen_zero(vmu->zonetag)) {
03663       /* Find the zone in the list */
03664       struct vm_zone *z;
03665       z = zones;
03666       while (z) {
03667          if (!strcmp(z->name, vmu->zonetag)) {
03668             the_zone = z;
03669             break;
03670          }
03671          z = z->next;
03672       }
03673    }
03674 
03675 /* No internal variable parsing for now, so we'll comment it out for the time being */
03676 #if 0
03677    /* Set the DIFF_* variables */
03678    localtime_r(&t, &time_now);
03679    tv_now = ast_tvnow();
03680    tnow = tv_now.tv_sec;
03681    localtime_r(&tnow,&time_then);
03682 
03683    /* Day difference */
03684    if (time_now.tm_year == time_then.tm_year)
03685       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
03686    else
03687       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
03688    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
03689 
03690    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
03691 #endif
03692    if (the_zone)
03693       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
03694        else if(!strcasecmp(chan->language,"se"))       /* SWEDISH syntax */
03695                res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
03696        else if(!strcasecmp(chan->language,"no"))       /* NORWEGIAN syntax */
03697                res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
03698    else if(!strcasecmp(chan->language,"de")) /* GERMAN syntax */
03699       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
03700    else if (!strcasecmp(chan->language,"nl"))   /* DUTCH syntax */
03701       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
03702    else if (!strcasecmp(chan->language,"he"))   /* HEBREW syntax */
03703       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' HM", NULL);
03704    else if (!strcasecmp(chan->language,"it"))      /* ITALIAN syntax */
03705       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);
03706    else if (!strcasecmp(chan->language,"gr"))
03707       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
03708    else if (!strcasecmp(chan->language,"pt_BR"))
03709       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);
03710    else
03711       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
03712 #if 0
03713    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
03714 #endif
03715    return res;
03716 }

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

Definition at line 3784 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_log(), ast_say_number(), ast_channel::language, LOG_DEBUG, and wait_file2().

Referenced by play_message().

03785 {
03786    int res = 0;
03787    int durationm;
03788    int durations;
03789    /* Verify that we have a duration for the message */
03790    if((duration == NULL))
03791       return res;
03792 
03793    /* Convert from seconds to minutes */
03794    durations=atoi(duration);
03795    durationm=(durations / 60);
03796 
03797    ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
03798 
03799    if((!res)&&(durationm>=minduration)) {
03800       res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, (char *) NULL);
03801       res = wait_file2(chan, vms, "vm-minutes");
03802    }
03803    return res;
03804 }

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

Definition at line 6669 of file app_voicemail.c.

References ast_channel_setoption(), AST_DIGIT_ANY, ast_log(), AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_streamfile(), ast_test_flag, ast_verbose(), ast_waitfordigit(), ast_waitstream(), ast_vm_user::context, DELETE, DISPOSE, INTRO, ast_channel::language, LOG_WARNING, ast_vm_user::mailbox, option_verbose, STORE, VERBOSE_PREFIX_3, vm_delete(), vm_exec(), VM_OPERATOR, and VM_REVIEW.

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

06672 {
06673    /* Record message & let caller review or re-record it, or set options if applicable */
06674    int res = 0;
06675    int cmd = 0;
06676    int max_attempts = 3;
06677    int attempts = 0;
06678    int recorded = 0;
06679    int message_exists = 0;
06680    signed char zero_gain = 0;
06681    char *acceptdtmf = "#";
06682    char *canceldtmf = "";
06683 
06684    /* Note that urgent and private are for flagging messages as such in the future */
06685  
06686    /* barf if no pointer passed to store duration in */
06687    if (duration == NULL) {
06688       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
06689       return -1;
06690    }
06691 
06692    cmd = '3';   /* Want to start by recording */
06693  
06694    while ((cmd >= 0) && (cmd != 't')) {
06695       switch (cmd) {
06696       case '1':
06697          if (!message_exists) {
06698             /* In this case, 1 is to record a message */
06699             cmd = '3';
06700             break;
06701          } else {
06702             /* Otherwise 1 is to save the existing message */
06703             if (option_verbose > 2)
06704                ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
06705             ast_streamfile(chan, "vm-msgsaved", chan->language);
06706             ast_waitstream(chan, "");
06707             STORE(recordfile, vmu->mailbox, vmu->context, -1);
06708             DISPOSE(recordfile, -1);
06709             cmd = 't';
06710             return res;
06711          }
06712       case '2':
06713          /* Review */
06714          if (option_verbose > 2)
06715             ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
06716          ast_streamfile(chan, recordfile, chan->language);
06717          cmd = ast_waitstream(chan, AST_DIGIT_ANY);
06718          break;
06719       case '3':
06720          message_exists = 0;
06721          /* Record */
06722          if (recorded == 1) {
06723             if (option_verbose > 2)
06724                ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
06725          } else { 
06726             if (option_verbose > 2)
06727                ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
06728          }
06729          if (recorded && outsidecaller) {
06730             cmd = ast_play_and_wait(chan, INTRO);
06731             cmd = ast_play_and_wait(chan, "beep");
06732          }
06733          recorded = 1;
06734          /* 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 */
06735          if (record_gain)
06736             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
06737          if (ast_test_flag(vmu, VM_OPERATOR))
06738             canceldtmf = "0";
06739          cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
06740          if (record_gain)
06741             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
06742          if (cmd == -1) {
06743          /* User has hung up, no options to give */
06744             return cmd;
06745          }
06746          if (cmd == '0') {
06747             break;
06748          } else if (cmd == '*') {
06749             break;
06750          } 
06751 #if 0       
06752          else if (vmu->review && (*duration < 5)) {
06753             /* Message is too short */
06754             if (option_verbose > 2)
06755                ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
06756             cmd = ast_play_and_wait(chan, "vm-tooshort");
06757             cmd = vm_delete(recordfile);
06758             break;
06759          }
06760          else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
06761             /* Message is all silence */
06762             if (option_verbose > 2)
06763                ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
06764             cmd = vm_delete(recordfile);
06765             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
06766             if (!cmd)
06767                cmd = ast_play_and_wait(chan, "vm-speakup");
06768             break;
06769          }
06770 #endif
06771          else {
06772             /* If all is well, a message exists */
06773             message_exists = 1;
06774             cmd = 0;
06775          }
06776          break;
06777       case '4':
06778       case '5':
06779       case '6':
06780       case '7':
06781       case '8':
06782       case '9':
06783       case '*':
06784       case '#':
06785          cmd = ast_play_and_wait(chan, "vm-sorry");
06786          break;
06787 #if 0 
06788 /*  XXX Commented out for the moment because of the dangers of deleting
06789     a message while recording (can put the message numbers out of sync) */
06790       case '*':
06791          /* Cancel recording, delete message, offer to take another message*/
06792          cmd = ast_play_and_wait(chan, "vm-deleted");
06793          cmd = vm_delete(recordfile);
06794          if (outsidecaller) {
06795             res = vm_exec(chan, NULL);
06796             return res;
06797          }
06798          else
06799             return 1;
06800 #endif
06801       case '0':
06802          if(!ast_test_flag(vmu, VM_OPERATOR)) {
06803             cmd = ast_play_and_wait(chan, "vm-sorry");
06804             break;
06805          }
06806          if (message_exists || recorded) {
06807             cmd = ast_play_and_wait(chan, "vm-saveoper");
06808             if (!cmd)
06809                cmd = ast_waitfordigit(chan, 3000);
06810             if (cmd == '1') {
06811                ast_play_and_wait(chan, "vm-msgsaved");
06812                cmd = '0';
06813             } else {
06814                ast_play_and_wait(chan, "vm-deleted");
06815                DELETE(recordfile, -1, recordfile);
06816                cmd = '0';
06817             }
06818          }
06819          return cmd;
06820       default:
06821          /* If the caller is an ouside caller, and the review option is enabled,
06822             allow them to review the message, but let the owner of the box review
06823             their OGM's */
06824          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
06825             return cmd;
06826          if (message_exists) {
06827             cmd = ast_play_and_wait(chan, "vm-review");
06828          }
06829          else {
06830             cmd = ast_play_and_wait(chan, "vm-torerecord");
06831             if (!cmd)
06832                cmd = ast_waitfordigit(chan, 600);
06833          }
06834          
06835          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
06836             cmd = ast_play_and_wait(chan, "vm-reachoper");
06837             if (!cmd)
06838                cmd = ast_waitfordigit(chan, 600);
06839          }
06840 #if 0
06841          if (!cmd)
06842             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
06843 #endif
06844          if (!cmd)
06845             cmd = ast_waitfordigit(chan, 6000);
06846          if (!cmd) {
06847             attempts++;
06848          }
06849          if (attempts > max_attempts) {
06850             cmd = 't';
06851          }
06852       }
06853    }
06854    if (outsidecaller)  
06855       ast_play_and_wait(chan, "vm-goodbye");
06856    if (cmd == 't')
06857       cmd = 0;
06858    return cmd;
06859  }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

Definition at line 426 of file app_voicemail.c.

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

Referenced by append_mailbox(), and find_user_realtime().

00427 {
00428    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00429    if (saydurationminfo)
00430       vmu->saydurationm = saydurationminfo;
00431    if (callcontext)
00432       ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00433    if (dialcontext)
00434       ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00435    if (exitcontext)
00436       ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00437    if (maxmsg)
00438       vmu->maxmsg = maxmsg;
00439 }

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

Definition at line 1628 of file app_voicemail.c.

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

Referenced by sendmail(), and sendpage().

01629 {
01630    char callerid[256];
01631    /* Prepare variables for substition in email body and subject */
01632    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
01633    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
01634    snprintf(passdata, passdatasize, "%d", msgnum);
01635    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
01636    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
01637    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
01638    pbx_builtin_setvar_helper(ast, "VM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller"));
01639    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (cidname ? cidname : "an unknown caller"));
01640    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
01641    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
01642 }

int reload ( void   ) 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
The return value is not used.

Definition at line 6373 of file app_voicemail.c.

References load_config().

06374 {
06375    return(load_config());
06376 }

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

Definition at line 1398 of file app_voicemail.c.

References ast_filerename().

01399 {
01400    char stxt[256];
01401    char dtxt[256];
01402    ast_filerename(sfn,dfn,NULL);
01403    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
01404    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
01405    rename(stxt, dtxt);
01406 }

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

Definition at line 2684 of file app_voicemail.c.

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

Referenced by open_mailbox().

02685 {
02686    /* we know max messages, so stop process when number is hit */
02687 
02688    int x,dest;
02689    char sfn[256];
02690    char dfn[256];
02691 
02692    if (vm_lock_path(dir))
02693       return ERROR_LOCK_PATH;
02694 
02695    for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
02696       make_file(sfn, sizeof(sfn), dir, x);
02697       if (EXISTS(dir, x, sfn, NULL)) {
02698          
02699          if(x != dest) {
02700             make_file(dfn, sizeof(dfn), dir, dest);
02701             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
02702          }
02703          
02704          dest++;
02705       }
02706    }
02707    ast_unlock_path(dir);
02708 
02709    return 0;
02710 }

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

Definition at line 611 of file app_voicemail.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::next, ast_vm_user::password, and users.

Referenced by vm_change_password(), and vm_change_password_shell().

00612 {
00613    /* This function could be made to generate one from a database, too */
00614    struct ast_vm_user *cur;
00615    int res = -1;
00616    ast_mutex_lock(&vmlock);
00617    cur = users;
00618    while (cur) {
00619       if ((!context || !strcasecmp(context, cur->context)) &&
00620          (!strcasecmp(mailbox, cur->mailbox)))
00621             break;
00622       cur=cur->next;
00623    }
00624    if (cur) {
00625       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00626       res = 0;
00627    }
00628    ast_mutex_unlock(&vmlock);
00629    return res;
00630 }

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

Definition at line 2343 of file app_voicemail.c.

References ast_log(), ast_safe_system(), ast_strlen_zero(), LOG_DEBUG, LOG_ERROR, and messagecount().

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

02344 {
02345    char arguments[255];
02346    char ext_context[256] = "";
02347    int newvoicemails = 0, oldvoicemails = 0;
02348 
02349    if (!ast_strlen_zero(context))
02350       snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
02351    else
02352       ast_copy_string(ext_context, extension, sizeof(ext_context));
02353 
02354    if (!ast_strlen_zero(externnotify)) {
02355       if (messagecount(ext_context, &newvoicemails, &oldvoicemails)) {
02356          ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
02357       } else {
02358          snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
02359          ast_log(LOG_DEBUG, "Executing %s\n", arguments);
02360          ast_safe_system(arguments);
02361       }
02362    }
02363 }

static int save_to_folder ( struct ast_vm_user vmu,
char *  dir,
int  msg,
char *  context,
char *  username,
int  box 
) [static]

Definition at line 2720 of file app_voicemail.c.

References ast_unlock_path(), create_dirpath(), ERROR_LOCK_PATH, EXISTS, make_file(), ast_vm_user::maxmsg, mbox(), and vm_lock_path().

Referenced by vm_execmain().

02721 {
02722    char sfn[256];
02723    char dfn[256];
02724    char ddir[256];
02725    char *dbox = mbox(box);
02726    int x;
02727    make_file(sfn, sizeof(sfn), dir, msg);
02728    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
02729 
02730    if (vm_lock_path(ddir))
02731       return ERROR_LOCK_PATH;
02732 
02733    for (x = 0; x < vmu->maxmsg; x++) {
02734       make_file(dfn, sizeof(dfn), ddir, x);
02735       if (!EXISTS(ddir, x, dfn, NULL))
02736          break;
02737    }
02738    if (x >= vmu->maxmsg) {
02739       ast_unlock_path(ddir);
02740       return -1;
02741    }
02742    if (strcmp(sfn, dfn)) {
02743       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
02744    }
02745    ast_unlock_path(ddir);
02746    
02747    return 0;
02748 }

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

Definition at line 2713 of file app_voicemail.c.

References AST_DIGIT_ANY, and ast_say_number().

Referenced by vm_execmain(), vm_intro_cz(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_it(), vm_intro_nl(), vm_intro_no(), and vm_intro_se().

02714 {
02715    int d;
02716    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
02717    return d;
02718 }

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

Definition at line 1644 of file app_voicemail.c.

References ast_channel_alloc(), ast_channel_free(), ast_localtime(), ast_log(), ast_safe_system(), ast_strlen_zero(), ast_test_flag, base_encode(), ast_vm_user::email, ast_vm_user::fullname, globalflags, host, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, vm_zone::name, vm_zone::next, pbx_substitute_variables_helper(), prep_email_sub_vars(), t, vm_zone::timezone, VM_ATTACH, VM_PBXSKIP, zones, and ast_vm_user::zonetag.

Referenced by forward_message(), and notify_new_message().

01645 {
01646    FILE *p=NULL;
01647    int pfd;
01648    char date[256];
01649    char host[MAXHOSTNAMELEN] = "";
01650    char who[256];
01651    char bound[256];
01652    char fname[256];
01653    char dur[256];
01654    char tmp[80] = "/tmp/astmail-XXXXXX";
01655    char tmp2[256];
01656    time_t t;
01657    struct tm tm;
01658    struct vm_zone *the_zone = NULL;
01659    if (vmu && ast_strlen_zero(vmu->email)) {
01660       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
01661       return(0);
01662    }
01663    if (!strcmp(format, "wav49"))
01664       format = "WAV";
01665    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));
01666    /* Make a temporary file instead of piping directly to sendmail, in case the mail
01667       command hangs */
01668    pfd = mkstemp(tmp);
01669    if (pfd > -1) {
01670       p = fdopen(pfd, "w");
01671       if (!p) {
01672          close(pfd);
01673          pfd = -1;
01674       }
01675    }
01676    if (p) {
01677       gethostname(host, sizeof(host)-1);
01678       if (strchr(srcemail, '@'))
01679          ast_copy_string(who, srcemail, sizeof(who));
01680       else {
01681          snprintf(who, sizeof(who), "%s@%s", srcemail, host);
01682       }
01683       snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
01684       time(&t);
01685 
01686       /* Does this user have a timezone specified? */
01687       if (!ast_strlen_zero(vmu->zonetag)) {
01688          /* Find the zone in the list */
01689          struct vm_zone *z;
01690          z = zones;
01691          while (z) {
01692             if (!strcmp(z->name, vmu->zonetag)) {
01693                the_zone = z;
01694                break;
01695             }
01696             z = z->next;
01697          }
01698       }
01699 
01700       if (the_zone)
01701          ast_localtime(&t,&tm,the_zone->timezone);
01702       else
01703          ast_localtime(&t,&tm,NULL);
01704       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm);
01705       fprintf(p, "Date: %s\n", date);
01706 
01707       /* Set date format for voicemail mail */
01708       strftime(date, sizeof(date), emaildateformat, &tm);
01709 
01710       if (*fromstring) {
01711          struct ast_channel *ast = ast_channel_alloc(0);
01712          if (ast) {
01713             char *passdata;
01714             int vmlen = strlen(fromstring)*3 + 200;
01715             if ((passdata = alloca(vmlen))) {
01716                memset(passdata, 0, vmlen);
01717                prep_email_sub_vars(ast,vmu,msgnum + 1,context,mailbox,cidnum, cidname,dur,date,passdata, vmlen);
01718                pbx_substitute_variables_helper(ast,fromstring,passdata,vmlen);
01719                fprintf(p, "From: %s <%s>\n",passdata,who);
01720             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01721             ast_channel_free(ast);
01722          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01723       } else
01724          fprintf(p, "From: Asterisk PBX <%s>\n", who);
01725       fprintf(p, "To: %s <%s>\n", vmu->fullname, vmu->email);
01726 
01727       if (emailsubject) {
01728          struct ast_channel *ast = ast_channel_alloc(0);
01729          if (ast) {
01730             char *passdata;
01731             int vmlen = strlen(emailsubject)*3 + 200;
01732             if ((passdata = alloca(vmlen))) {
01733                memset(passdata, 0, vmlen);
01734                prep_email_sub_vars(ast,vmu,msgnum + 1,context,mailbox,cidnum, cidname,dur,date,passdata, vmlen);
01735                pbx_substitute_variables_helper(ast,emailsubject,passdata,vmlen);
01736                fprintf(p, "Subject: %s\n",passdata);
01737             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01738             ast_channel_free(ast);
01739          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01740       } else
01741       if (*emailtitle) {
01742          fprintf(p, emailtitle, msgnum + 1, mailbox) ;
01743          fprintf(p,"\n") ;
01744       } else if (ast_test_flag((&globalflags), VM_PBXSKIP))
01745          fprintf(p, "Subject: New message %d in mailbox %s\n", msgnum + 1, mailbox);
01746       else
01747          fprintf(p, "Subject: [PBX]: New message %d in mailbox %s\n", msgnum + 1, mailbox);
01748       fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>\n", msgnum, (unsigned int)rand(), mailbox, getpid(), host);
01749       fprintf(p, "MIME-Version: 1.0\n");
01750       if (attach_user_voicemail) {
01751          /* Something unique. */
01752          snprintf(bound, sizeof(bound), "voicemail_%d%s%d%d", msgnum, mailbox, getpid(), (unsigned int)rand());
01753 
01754          fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"\n\n\n", bound);
01755 
01756          fprintf(p, "--%s\n", bound);
01757       }
01758       fprintf(p, "Content-Type: text/plain; charset=%s\nContent-Transfer-Encoding: 8bit\n\n", charset);
01759       if (emailbody) {
01760          struct ast_channel *ast = ast_channel_alloc(0);
01761          if (ast) {
01762             char *passdata;
01763             int vmlen = strlen(emailbody)*3 + 200;
01764             if ((passdata = alloca(vmlen))) {
01765                memset(passdata, 0, vmlen);
01766                prep_email_sub_vars(ast,vmu,msgnum + 1,context,mailbox,cidnum, cidname,dur,date,passdata, vmlen);
01767                pbx_substitute_variables_helper(ast,emailbody,passdata,vmlen);
01768                fprintf(p, "%s\n",passdata);
01769             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01770             ast_channel_free(ast);
01771          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01772       } else {
01773          fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message (number %d)\n"
01774 
01775          "in mailbox %s from %s, on %s so you might\n"
01776          "want to check it when you get a chance.  Thanks!\n\n\t\t\t\t--Asterisk\n\n", vmu->fullname, 
01777          dur, msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
01778       }
01779       if (attach_user_voicemail) {
01780          /* Eww. We want formats to tell us their own MIME type */
01781          char *ctype = "audio/x-";
01782          if (!strcasecmp(format, "ogg"))
01783             ctype = "application/";
01784       
01785          fprintf(p, "--%s\n", bound);
01786          fprintf(p, "Content-Type: %s%s; name=\"msg%04d.%s\"\n", ctype, format, msgnum, format);
01787          fprintf(p, "Content-Transfer-Encoding: base64\n");
01788          fprintf(p, "Content-Description: Voicemail sound attachment.\n");
01789          fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"\n\n", msgnum, format);
01790 
01791          snprintf(fname, sizeof(fname), "%s.%s", attach, format);
01792          base_encode(fname, p);
01793          fprintf(p, "\n\n--%s--\n.\n", bound);
01794       }
01795       fclose(p);
01796       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
01797       ast_safe_system(tmp2);
01798       ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
01799    } else {
01800       ast_log(LOG_WARNING, "Unable to launch '%s'\n", mailcmd);
01801       return -1;
01802    }
01803    return 0;
01804 }

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

Definition at line 1806 of file app_voicemail.c.

References ast_channel_alloc(), ast_channel_free(), ast_localtime(), ast_log(), ast_safe_system(), ast_strlen_zero(), host, LOG_DEBUG, LOG_WARNING, vm_zone::name, vm_zone::next, pbx_substitute_variables_helper(), prep_email_sub_vars(), t, vm_zone::timezone, zones, and ast_vm_user::zonetag.

Referenced by forward_message(), and notify_new_message().

01807 {
01808    FILE *p=NULL;
01809    int pfd;
01810    char date[256];
01811    char host[MAXHOSTNAMELEN]="";
01812    char who[256];
01813    char dur[256];
01814    char tmp[80] = "/tmp/astmail-XXXXXX";
01815    char tmp2[256];
01816    time_t t;
01817    struct tm tm;
01818    struct vm_zone *the_zone = NULL;
01819    pfd = mkstemp(tmp);
01820 
01821    if (pfd > -1) {
01822       p = fdopen(pfd, "w");
01823       if (!p) {
01824          close(pfd);
01825          pfd = -1;
01826       }
01827    }
01828 
01829    if (p) {
01830       gethostname(host, sizeof(host)-1);
01831       if (strchr(srcemail, '@'))
01832          ast_copy_string(who, srcemail, sizeof(who));
01833       else {
01834          snprintf(who, sizeof(who), "%s@%s", srcemail, host);
01835       }
01836       snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
01837       time(&t);
01838 
01839       /* Does this user have a timezone specified? */
01840       if (!ast_strlen_zero(vmu->zonetag)) {
01841          /* Find the zone in the list */
01842          struct vm_zone *z;
01843          z = zones;
01844          while (z) {
01845             if (!strcmp(z->name, vmu->zonetag)) {
01846                the_zone = z;
01847                break;
01848             }
01849             z = z->next;
01850          }
01851       }
01852 
01853       if (the_zone)
01854          ast_localtime(&t,&tm,the_zone->timezone);
01855       else
01856          ast_localtime(&t,&tm,NULL);
01857 
01858       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm);
01859       fprintf(p, "Date: %s\n", date);
01860 
01861       if (*pagerfromstring) {
01862          struct ast_channel *ast = ast_channel_alloc(0);
01863          if (ast) {
01864             char *passdata;
01865             int vmlen = strlen(fromstring)*3 + 200;
01866             if ((passdata = alloca(vmlen))) {
01867                memset(passdata, 0, vmlen);
01868                prep_email_sub_vars(ast,vmu,msgnum + 1,context,mailbox,cidnum, cidname,dur,date,passdata, vmlen);
01869                pbx_substitute_variables_helper(ast,pagerfromstring,passdata,vmlen);
01870                fprintf(p, "From: %s <%s>\n",passdata,who);
01871             } else 
01872                ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01873             ast_channel_free(ast);
01874          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01875       } else
01876          fprintf(p, "From: Asterisk PBX <%s>\n", who);
01877       fprintf(p, "To: %s\n", pager);
01878                if (pagersubject) {
01879                        struct ast_channel *ast = ast_channel_alloc(0);
01880                        if (ast) {
01881                                char *passdata;
01882                                int vmlen = strlen(pagersubject)*3 + 200;
01883                                if ((passdata = alloca(vmlen))) {
01884                                        memset(passdata, 0, vmlen);
01885                                        prep_email_sub_vars(ast,vmu,msgnum + 1,context,mailbox,cidnum, cidname,dur,date,passdata, vmlen);
01886                                        pbx_substitute_variables_helper(ast,pagersubject,passdata,vmlen);
01887                                        fprintf(p, "Subject: %s\n\n",passdata);
01888                                } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01889                                ast_channel_free(ast);
01890                        } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01891                } else
01892                        fprintf(p, "Subject: New VM\n\n");
01893       strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
01894                if (pagerbody) {
01895                        struct ast_channel *ast = ast_channel_alloc(0);
01896                        if (ast) {
01897                                char *passdata;
01898                                int vmlen = strlen(pagerbody)*3 + 200;
01899                                if ((passdata = alloca(vmlen))) {
01900                                        memset(passdata, 0, vmlen);
01901                                        prep_email_sub_vars(ast,vmu,msgnum + 1,context,mailbox,cidnum, cidname,dur,date,passdata, vmlen);
01902                                        pbx_substitute_variables_helper(ast,pagerbody,passdata,vmlen);
01903                                        fprintf(p, "%s\n",passdata);
01904                                } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01905                                ast_channel_free(ast);
01906                        } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01907                } else {
01908                        fprintf(p, "New %s long msg in box %s\n"
01909                                        "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
01910                }
01911       fclose(p);
01912       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
01913       ast_safe_system(tmp2);
01914       ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd);
01915    } else {
01916       ast_log(LOG_WARNING, "Unable to launch '%s'\n", mailcmd);
01917       return -1;
01918    }
01919    return 0;
01920 }

int unload_module ( void   ) 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.

Definition at line 6378 of file app_voicemail.c.

References ast_cli_unregister(), ast_uninstall_vm_functions(), ast_unregister_application(), show_voicemail_users_cli, show_voicemail_zones_cli, and STANDARD_HANGUP_LOCALUSERS.

06379 {
06380    int res;
06381    
06382    res = ast_unregister_application(app);
06383    res |= ast_unregister_application(app2);
06384    res |= ast_unregister_application(app3);
06385    res |= ast_unregister_application(app4);
06386    res |= ast_cli_unregister(&show_voicemail_users_cli);
06387    res |= ast_cli_unregister(&show_voicemail_zones_cli);
06388    ast_uninstall_vm_functions();
06389    
06390    STANDARD_HANGUP_LOCALUSERS;
06391 
06392    return res;
06393 }

int usecount ( void   ) 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 6862 of file app_voicemail.c.

References STANDARD_USECOUNT.

06863 {
06864    int res;
06865    STANDARD_USECOUNT(res);
06866    return res;
06867 }

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 5038 of file app_voicemail.c.

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

Referenced by vm_execmain(), and vmauthenticate().

05041 {
05042    int useadsi=0, valid=0, logretries=0;
05043    char password[AST_MAX_EXTENSION]="", *passptr;
05044    struct ast_vm_user vmus, *vmu = NULL;
05045 
05046    /* If ADSI is supported, setup login screen */
05047    adsi_begin(chan, &useadsi);
05048    if (!skipuser && useadsi)
05049       adsi_login(chan);
05050    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
05051       ast_log(LOG_WARNING, "Couldn't stream login file\n");
05052       return -1;
05053    }
05054    
05055    /* Authenticate them and get their mailbox/password */
05056    
05057    while (!valid && (logretries < maxlogins)) {
05058       /* Prompt for, and read in the username */
05059       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
05060          ast_log(LOG_WARNING, "Couldn't read username\n");
05061          return -1;
05062       }
05063       if (ast_strlen_zero(mailbox)) {
05064          if (chan->cid.cid_num) {
05065             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
05066          } else {
05067             if (option_verbose > 2)
05068                ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");  
05069             return -1;
05070          }
05071       }
05072       if (useadsi)
05073          adsi_password(chan);
05074 
05075       if (!ast_strlen_zero(prefix)) {
05076          char fullusername[80] = "";
05077          ast_copy_string(fullusername, prefix, sizeof(fullusername));
05078          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
05079          ast_copy_string(mailbox, fullusername, mailbox_size);
05080       }
05081 
05082       vmu = find_user(&vmus, context, mailbox);
05083       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
05084          /* saved password is blank, so don't bother asking */
05085          password[0] = '\0';
05086       } else {
05087          if (ast_streamfile(chan, "vm-password", chan->language)) {
05088             ast_log(LOG_WARNING, "Unable to stream password file\n");
05089             return -1;
05090          }
05091          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
05092             ast_log(LOG_WARNING, "Unable to read password\n");
05093             return -1;
05094          }
05095       }
05096 
05097       if (vmu) {
05098          passptr = vmu->password;
05099          if (passptr[0] == '-') passptr++;
05100       }
05101       if (vmu && !strcmp(passptr, password))
05102          valid++;
05103       else {
05104          if (option_verbose > 2)
05105             ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
05106          if (!ast_strlen_zero(prefix))
05107             mailbox[0] = '\0';
05108       }
05109       logretries++;
05110       if (!valid) {
05111          if (skipuser || logretries >= maxlogins) {
05112             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
05113                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
05114                return -1;
05115             }
05116          } else {
05117             if (useadsi)
05118                adsi_login(chan);
05119             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
05120                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
05121                return -1;
05122             }
05123          }
05124          if (ast_waitstream(chan, "")) /* Channel is hung up */
05125             return -1;
05126       }
05127    }
05128    if (!valid && (logretries >= maxlogins)) {
05129       ast_stopstream(chan);
05130       ast_play_and_wait(chan, "vm-goodbye");
05131       return -1;
05132    }
05133    if (vmu && !skipuser) {
05134       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
05135    }
05136    return 0;
05137 }

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

Definition at line 5717 of file app_voicemail.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_goto_if_exists(), ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::context, find_user(), LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, LOG_WARNING, mbox(), option_priority_jumping, and pbx_builtin_setvar_helper().

Referenced by load_module().

05718 {
05719    struct localuser *u;
05720    struct ast_vm_user svm;
05721    char *context, *box;
05722    int priority_jump = 0;
05723    AST_DECLARE_APP_ARGS(args,
05724       AST_APP_ARG(mbox);
05725       AST_APP_ARG(options);
05726    );
05727 
05728    if (ast_strlen_zero(data)) {
05729       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
05730       return -1;
05731    }
05732 
05733    LOCAL_USER_ADD(u);
05734 
05735    box = ast_strdupa(data);
05736    if (!box) {
05737       ast_log(LOG_ERROR, "Out of memory\n");
05738       LOCAL_USER_REMOVE(u);
05739       return -1;
05740    }
05741 
05742    AST_STANDARD_APP_ARGS(args, box);
05743 
05744    if (args.options) {
05745       if (strchr(args.options, 'j'))
05746          priority_jump = 1;
05747    }
05748 
05749    if ((context = strchr(args.mbox, '@'))) {
05750       *context = '\0';
05751       context++;
05752    }
05753 
05754    if (find_user(&svm, context, args.mbox)) {
05755       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
05756       if (priority_jump || option_priority_jumping)
05757          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
05758             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);
05759    } else
05760       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
05761    LOCAL_USER_REMOVE(u);
05762    return 0;
05763 }

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

Definition at line 5023 of file app_voicemail.c.

References ast_channel::language, vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_it(), and vm_browse_messages_pt().

Referenced by vm_execmain().

05024 {
05025    if (!strcasecmp(chan->language, "es")) {  /* SPANISH */
05026       return vm_browse_messages_es(chan, vms, vmu);
05027    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN */
05028       return vm_browse_messages_it(chan, vms, vmu);
05029    } else if (!strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) {   /* PORTUGUESE */
05030       return vm_browse_messages_pt(chan, vms, vmu);
05031    } else if (!strcasecmp(chan->language, "gr")){
05032       return vm_browse_messages_gr(chan, vms, vmu);   /* GREEK */
05033    } else { /* Default to English syntax */
05034       return vm_browse_messages_en(chan, vms, vmu);
05035    }
05036 }

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

Definition at line 4946 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

04947 {
04948    int cmd=0;
04949 
04950    if (vms->lastmsg > -1) {
04951       cmd = play_message(chan, vmu, vms);
04952    } else {
04953       cmd = ast_play_and_wait(chan, "vm-youhave");
04954       if (!cmd) 
04955          cmd = ast_play_and_wait(chan, "vm-no");
04956       if (!cmd) {
04957          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
04958          cmd = ast_play_and_wait(chan, vms->fn);
04959       }
04960       if (!cmd)
04961          cmd = ast_play_and_wait(chan, "vm-messages");
04962    }
04963    return cmd;
04964 }

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

Definition at line 4986 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

04987 {
04988    int cmd=0;
04989 
04990    if (vms->lastmsg > -1) {
04991       cmd = play_message(chan, vmu, vms);
04992    } else {
04993       cmd = ast_play_and_wait(chan, "vm-youhaveno");
04994       if (!cmd)
04995          cmd = ast_play_and_wait(chan, "vm-messages");
04996       if (!cmd) {
04997          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
04998          cmd = ast_play_and_wait(chan, vms->fn);
04999       }
05000    }
05001    return cmd;
05002 }

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

Definition at line 4918 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

04919 {
04920    int cmd=0;
04921 
04922    if (vms->lastmsg > -1) {
04923       cmd = play_message(chan, vmu, vms);
04924    } else {
04925       cmd = ast_play_and_wait(chan, "vm-youhaveno");
04926       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
04927          if (!cmd) {
04928             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
04929             cmd = ast_play_and_wait(chan, vms->fn);
04930          }
04931          if (!cmd)
04932             cmd = ast_play_and_wait(chan, "vm-messages");
04933       } else {
04934          if (!cmd)
04935             cmd = ast_play_and_wait(chan, "vm-messages");
04936          if (!cmd) {
04937             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
04938             cmd = ast_play_and_wait(chan, vms->fn);
04939          }
04940       }
04941    } 
04942    return cmd;
04943 }

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

Definition at line 4967 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

04968 {
04969         int cmd=0;
04970 
04971         if (vms->lastmsg > -1) {
04972                 cmd = play_message(chan, vmu, vms);
04973         } else {
04974                 cmd = ast_play_and_wait(chan, "vm-no");
04975                 if (!cmd)
04976                         cmd = ast_play_and_wait(chan, "vm-message");
04977                 if (!cmd) {
04978                         snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
04979                         cmd = ast_play_and_wait(chan, vms->fn);
04980                 }
04981         }
04982         return cmd;
04983 }

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

Definition at line 5005 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

05006 {
05007    int cmd=0;
05008 
05009    if (vms->lastmsg > -1) {
05010       cmd = play_message(chan, vmu, vms);
05011    } else {
05012       cmd = ast_play_and_wait(chan, "vm-no");
05013       if (!cmd) {
05014          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
05015          cmd = ast_play_and_wait(chan, vms->fn);
05016       }
05017       if (!cmd)
05018          cmd = ast_play_and_wait(chan, "vm-messages");
05019    }
05020    return cmd;
05021 }

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

Definition at line 632 of file app_voicemail.c.

References ast_config_AST_CONFIG_DIR, AST_CONFIG_MAX_PATH, ast_log(), ast_strlen_zero(), change_password_realtime(), ast_vm_user::context, inbuf(), LOG_WARNING, ast_vm_user::mailbox, pass, ast_vm_user::password, reset_user_pw(), and user.

Referenced by vm_newuser(), and vm_options().

00633 {
00634    /*  There's probably a better way of doing this. */
00635    /*  That's why I've put the password change in a separate function. */
00636    /*  This could also be done with a database function */
00637    
00638    FILE *configin;
00639    FILE *configout;
00640    int linenum=0;
00641    char inbuf[256];
00642    char orig[256];
00643    char currcontext[256] ="";
00644    char tmpin[AST_CONFIG_MAX_PATH];
00645    char tmpout[AST_CONFIG_MAX_PATH];
00646    struct stat statbuf;
00647 
00648    if (!change_password_realtime(vmu, newpassword))
00649       return;
00650 
00651    snprintf(tmpin, sizeof(tmpin), "%s/voicemail.conf", ast_config_AST_CONFIG_DIR);
00652    snprintf(tmpout, sizeof(tmpout), "%s/voicemail.conf.new", ast_config_AST_CONFIG_DIR);
00653    configin = fopen(tmpin,"r");
00654    if (configin)
00655       configout = fopen(tmpout,"w+");
00656    else
00657       configout = NULL;
00658    if (!configin || !configout) {
00659       if (configin)
00660          fclose(configin);
00661       else
00662          ast_log(LOG_WARNING, "Warning: Unable to open '%s' for reading: %s\n", tmpin, strerror(errno));
00663       if (configout)
00664          fclose(configout);
00665       else
00666          ast_log(LOG_WARNING, "Warning: Unable to open '%s' for writing: %s\n", tmpout, strerror(errno));
00667          return;
00668    }
00669 
00670    while (!feof(configin)) {
00671       char *user = NULL, *pass = NULL, *rest = NULL, *comment = NULL, *tmpctx = NULL, *tmpctxend = NULL;
00672 
00673       /* Read in the line */
00674       if (fgets(inbuf, sizeof(inbuf), configin) == NULL)
00675          continue;
00676       linenum++;
00677 
00678       /* Make a backup of it */
00679       ast_copy_string(orig, inbuf, sizeof(orig));
00680 
00681       /*
00682         Read the file line by line, split each line into a comment and command section
00683         only parse the command portion of the line
00684       */
00685       if (inbuf[strlen(inbuf) - 1] == '\n')
00686          inbuf[strlen(inbuf) - 1] = '\0';
00687 
00688       if ((comment = strchr(inbuf, ';')))
00689          *comment++ = '\0'; /* Now inbuf is terminated just before the comment */
00690 
00691       if (ast_strlen_zero(inbuf)) {
00692          fprintf(configout, "%s", orig);
00693          continue;
00694       }
00695 
00696       /* Check for a context, first '[' to first ']' */
00697       if ((tmpctx = strchr(inbuf, '['))) {
00698          tmpctxend = strchr(tmpctx, ']');
00699          if (tmpctxend) {
00700             /* Valid context */
00701             ast_copy_string(currcontext, tmpctx + 1, tmpctxend - tmpctx);
00702             fprintf(configout, "%s", orig);
00703             continue;
00704          }
00705       }
00706 
00707       /* This isn't a context line, check for MBX => PSWD... */
00708       user = inbuf;
00709       if ((pass = strchr(user, '='))) {
00710          /* We have a line in the form of aaaaa=aaaaaa */
00711          *pass++ = '\0';
00712 
00713          user = ast_strip(user);
00714 
00715          if (*pass == '>')
00716             *pass++ = '\0';
00717 
00718          pass = ast_skip_blanks(pass);
00719 
00720          /* 
00721             Since no whitespace allowed in fields, or more correctly white space
00722             inside the fields is there for a purpose, we can just terminate pass
00723             at the comma or EOL whichever comes first.
00724          */
00725          if ((rest = strchr(pass, ',')))
00726             *rest++ = '\0';
00727       } else {
00728          user = NULL;
00729       }        
00730 
00731       /* Compare user, pass AND context */
00732       if (!ast_strlen_zero(user) && !strcmp(user, vmu->mailbox) &&
00733           !ast_strlen_zero(pass) && !strcmp(pass, vmu->password) &&
00734           !strcasecmp(currcontext, vmu->context)) {
00735          /* This is the line */
00736          if (rest) {
00737             fprintf(configout, "%s => %s,%s", user, newpassword, rest);
00738          } else {
00739             fprintf(configout, "%s => %s", user, newpassword);
00740          }
00741          /* If there was a comment on the line print it out */
00742          if (comment) {
00743             fprintf(configout, ";%s\n", comment);
00744          } else {
00745             fprintf(configout, "\n");
00746          }
00747       } else {
00748          /* Put it back like it was */
00749          fprintf(configout, "%s", orig);
00750       }
00751    }
00752    fclose(configin);
00753    fclose(configout);
00754 
00755    stat(tmpin, &statbuf);
00756    chmod(tmpout, statbuf.st_mode);
00757    chown(tmpout, statbuf.st_uid, statbuf.st_gid);
00758    unlink(tmpin);
00759    rename(tmpout, tmpin);
00760    reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00761    ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00762 }

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

Definition at line 764 of file app_voicemail.c.

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

Referenced by vm_newuser(), and vm_options().

00765 {
00766    char buf[255];
00767    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00768    if (!ast_safe_system(buf)) {
00769       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00770       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00771    }
00772 }

static int vm_delete ( char *  file  )  [static]

Definition at line 1488 of file app_voicemail.c.

References ast_filedelete().

Referenced by play_record_review().

01489 {
01490    char *txt;
01491    int txtsize = 0;
01492 
01493    txtsize = (strlen(file) + 5)*sizeof(char);
01494    txt = (char *)alloca(txtsize);
01495    /* Sprintf here would safe because we alloca'd exactly the right length,
01496     * but trying to eliminate all sprintf's anyhow
01497     */
01498    snprintf(txt, txtsize, "%s.txt", file);
01499    unlink(txt);
01500    return ast_filedelete(file, NULL);
01501 }

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

Definition at line 5585 of file app_voicemail.c.

References ast_channel::_state, ast_answer(), ast_app_getdata(), ast_app_parse_options(), ast_app_separate_args(), ast_copy_flags, ast_goto_if_exists(), ast_log(), ast_set_flag, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, ast_flags::flags, leave_voicemail(), LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, LOG_WARNING, OPT_ARG_ARRAY_SIZE, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_PRIORITY_JUMP, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, option_priority_jumping, and pbx_builtin_setvar_helper().

Referenced by load_module(), and play_record_review().

05586 {
05587    int res = 0;
05588    struct localuser *u;
05589    char *tmp;
05590    struct leave_vm_options leave_options;
05591    int argc;
05592    char *argv[2];
05593    struct ast_flags flags = { 0 };
05594    char *opts[OPT_ARG_ARRAY_SIZE];
05595    
05596    LOCAL_USER_ADD(u);
05597    
05598    memset(&leave_options, 0, sizeof(leave_options));
05599 
05600    if (chan->_state != AST_STATE_UP)
05601       ast_answer(chan);
05602 
05603    if (!ast_strlen_zero(data)) {
05604       tmp = ast_strdupa((char *)data);
05605       if (!tmp) {
05606          ast_log(LOG_ERROR, "Out of memory\n");
05607          LOCAL_USER_REMOVE(u);
05608          return -1;
05609       }
05610       argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
05611       if (argc == 2) {
05612          if (ast_app_parse_options(vm_app_options, &flags, opts, argv[1])) {
05613             LOCAL_USER_REMOVE(u);
05614             return -1;
05615          }
05616          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
05617          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
05618             int gain;
05619 
05620             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
05621                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
05622                LOCAL_USER_REMOVE(u);
05623                return -1;
05624             } else {
05625                leave_options.record_gain = (signed char) gain;
05626             }
05627          }
05628       } else {
05629          /* old style options parsing */
05630          while (*argv[0]) {
05631             if (*argv[0] == 's') {
05632                ast_set_flag(&leave_options, OPT_SILENT);
05633                argv[0]++;
05634             } else if (*argv[0] == 'b') {
05635                ast_set_flag(&leave_options, OPT_BUSY_GREETING);
05636                argv[0]++;
05637             } else if (*argv[0] == 'u') {
05638                ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
05639                argv[0]++;
05640             } else if (*argv[0] == 'j') {
05641                ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
05642                argv[0]++;
05643             } else 
05644                break;
05645          }
05646       }
05647    } else {
05648       char tmp[256];
05649       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
05650       if (res < 0) {
05651          LOCAL_USER_REMOVE(u);
05652          return res;
05653       }
05654       if (ast_strlen_zero(tmp)) {
05655          LOCAL_USER_REMOVE(u);
05656          return 0;
05657       }
05658       argv[0] = ast_strdupa(tmp);
05659    }
05660 
05661    res = leave_voicemail(chan, argv[0], &leave_options);
05662 
05663    if (res == ERROR_LOCK_PATH) {
05664       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
05665       /*Send the call to n+101 priority, where n is the current priority*/
05666       if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || option_priority_jumping)
05667          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
05668             ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
05669       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
05670       res = 0;
05671    }
05672    
05673    LOCAL_USER_REMOVE(u);
05674 
05675    return res;
05676 }

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

Definition at line 5139 of file app_voicemail.c.

References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), adsi_unload_session(), advanced_options(), ast_answer(), ast_app_parse_options(), ast_app_separate_args(), ast_log(), ast_play_and_wait(), ast_set_flag, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_waitfordigit(), ast_vm_user::callback, calloc, close_mailbox(), ast_vm_user::context, create_dirpath(), dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), ast_flags::flags, forward_message(), free, free_user(), get_folder2(), globalflags, has_voicemail(), ast_vm_user::language, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_NOTICE, LOG_WARNING, ast_vm_user::mailbox, make_file(), manager_event(), ast_vm_user::maxmsg, mbox(), open_mailbox(), OPT_ARG_ARRAY_SIZE, OPT_ARG_RECORDGAIN, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, option_verbose, ast_vm_user::password, play_message(), run_externnotify(), save_to_folder(), say_and_wait(), 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, and VM_SVMAIL.

Referenced by load_module().

05140 {
05141    /* XXX This is, admittedly, some pretty horrendus code.  For some
05142       reason it just seemed a lot easier to do with GOTO's.  I feel
05143       like I'm back in my GWBASIC days. XXX */
05144    int res=-1;
05145    int cmd=0;
05146    int valid = 0;
05147    struct localuser *u;
05148    char prefixstr[80] ="";
05149    char ext_context[256]="";
05150    int box;
05151    int useadsi = 0;
05152    int skipuser = 0;
05153    struct vm_state vms;
05154    struct ast_vm_user *vmu = NULL, vmus;
05155    char *context=NULL;
05156    int silentexit = 0;
05157    struct ast_flags flags = { 0 };
05158    signed char record_gain = 0;
05159 
05160    LOCAL_USER_ADD(u);
05161 
05162    memset(&vms, 0, sizeof(vms));
05163    vms.lastmsg = -1;
05164 
05165    memset(&vmus, 0, sizeof(vmus));
05166 
05167    if (chan->_state != AST_STATE_UP)
05168       ast_answer(chan);
05169 
05170    if (!ast_strlen_zero(data)) {
05171       char *tmp;
05172       int argc;
05173       char *argv[2];
05174       char *opts[OPT_ARG_ARRAY_SIZE];
05175 
05176       tmp = ast_strdupa(data);
05177       argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
05178       if (argc == 2) {
05179          if (ast_app_parse_options(vm_app_options, &flags, opts, argv[1])) {
05180             LOCAL_USER_REMOVE(u);
05181             return -1;
05182          }
05183          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
05184             int gain;
05185 
05186             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
05187                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
05188                LOCAL_USER_REMOVE(u);
05189                return -1;
05190             } else {
05191                record_gain = (signed char) gain;
05192             }
05193          }
05194       } else {
05195          /* old style options parsing */
05196          while (*argv[0]) {
05197             if (*argv[0] == 's') {
05198                ast_set_flag(&flags, OPT_SILENT);
05199                argv[0]++;
05200             } else if (*argv[0] == 'p') {
05201                ast_set_flag(&flags, OPT_PREPEND_MAILBOX);
05202                argv[0]++;
05203             } else 
05204                break;
05205          }
05206 
05207       }
05208 
05209       valid = ast_test_flag(&flags, OPT_SILENT);
05210 
05211       if ((context = strchr(argv[0], '@')))
05212          *context++ = '\0';
05213 
05214       if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
05215          ast_copy_string(prefixstr, argv[0], sizeof(prefixstr));
05216       else
05217          ast_copy_string(vms.username, argv[0], sizeof(vms.username));
05218 
05219       if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
05220          skipuser++;
05221       else {
05222          if (!ast_strlen_zero(vms.username))
05223             ast_log(LOG_NOTICE, "Specified user '%s%s%s' not found (check voicemail.conf and/or realtime config).  Falling back to authentication mode.\n", vms.username, context ? "@" : "", context ? context : "");
05224          valid = 0;
05225       }
05226    }
05227 
05228    if (!valid)
05229       res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
05230 
05231    if (!res) {
05232       valid = 1;
05233       if (!skipuser)
05234          vmu = &vmus;
05235    } else {
05236       res = 0;
05237    }
05238 
05239    /* If ADSI is supported, setup login screen */
05240    adsi_begin(chan, &useadsi);
05241 
05242    if (!valid)
05243       goto out;
05244 
05245    vms.deleted = calloc(vmu->maxmsg, sizeof(int));
05246    vms.heard = calloc(vmu->maxmsg, sizeof(int));
05247    
05248    /* Set language from config to override channel language */
05249    if (!ast_strlen_zero(vmu->language))
05250       ast_copy_string(chan->language, vmu->language, sizeof(chan->language));
05251    create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
05252    /* Retrieve old and new message counts */
05253    res = open_mailbox(&vms, vmu, 1);
05254    if (res == ERROR_LOCK_PATH)
05255       goto out;
05256    vms.oldmessages = vms.lastmsg + 1;
05257    /* Start in INBOX */
05258    res = open_mailbox(&vms, vmu, 0);
05259    if (res == ERROR_LOCK_PATH)
05260       goto out;
05261    vms.newmessages = vms.lastmsg + 1;
05262       
05263    /* Select proper mailbox FIRST!! */
05264    if (!vms.newmessages && vms.oldmessages) {
05265       /* If we only have old messages start here */
05266       res = open_mailbox(&vms, vmu, 1);
05267       if (res == ERROR_LOCK_PATH)
05268          goto out;
05269    }
05270 
05271    if (useadsi)
05272       adsi_status(chan, &vms);
05273    res = 0;
05274 
05275    /* Check to see if this is a new user */
05276    if (!strcasecmp(vmu->mailbox, vmu->password) && 
05277        (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) {
05278       if (ast_play_and_wait(chan, "vm-newuser") == -1)
05279          ast_log(LOG_WARNING, "Couldn't stream new user file\n");
05280       cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
05281       if ((cmd == 't') || (cmd == '#')) {
05282          /* Timeout */
05283          res = 0;
05284          goto out;
05285       } else if (cmd < 0) {
05286          /* Hangup */
05287          res = -1;
05288          goto out;
05289       }
05290    }
05291 
05292    cmd = vm_intro(chan, &vms);
05293 
05294    vms.repeats = 0;
05295    vms.starting = 1;
05296    while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
05297       /* Run main menu */
05298       switch(cmd) {
05299       case '1':
05300          vms.curmsg = 0;
05301          /* Fall through */
05302       case '5':
05303          cmd = vm_browse_messages(chan, &vms, vmu);
05304          break;
05305       case '2': /* Change folders */
05306          if (useadsi)
05307             adsi_folders(chan, 0, "Change to folder...");
05308          cmd = get_folder2(chan, "vm-changeto", 0);
05309          if (cmd == '#') {
05310             cmd = 0;
05311          } else if (cmd > 0) {
05312             cmd = cmd - '0';
05313             res = close_mailbox(&vms, vmu);
05314             if (res == ERROR_LOCK_PATH)
05315                goto out;
05316             res = open_mailbox(&vms, vmu, cmd);
05317             if (res == ERROR_LOCK_PATH)
05318                goto out;
05319             cmd = 0;
05320          }
05321          if (useadsi)
05322             adsi_status2(chan, &vms);
05323             
05324          if (!cmd)
05325             cmd = vm_play_folder_name(chan, vms.vmbox);
05326 
05327          vms.starting = 1;
05328          break;
05329       case '3': /* Advanced options */
05330          cmd = 0;
05331          vms.repeats = 0;
05332          while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
05333             switch(cmd) {
05334             case '1': /* Reply */
05335                if (vms.lastmsg > -1 && !vms.starting) {
05336                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
05337                   if (cmd == ERROR_LOCK_PATH) {
05338                      res = cmd;
05339                      goto out;
05340                   }
05341                } else
05342                   cmd = ast_play_and_wait(chan, "vm-sorry");
05343                cmd = 't';
05344                break;
05345             case '2': /* Callback */
05346                if (option_verbose > 2 && !vms.starting)
05347                   ast_verbose( VERBOSE_PREFIX_3 "Callback Requested\n");
05348                if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
05349                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
05350                   if (cmd == 9) {
05351                      silentexit = 1;
05352                      goto out;
05353                   } else if (cmd == ERROR_LOCK_PATH) {
05354                      res = cmd;
05355                      goto out;
05356                   }
05357                }
05358                else 
05359                   cmd = ast_play_and_wait(chan, "vm-sorry");
05360                cmd = 't';
05361                break;
05362             case '3': /* Envelope */
05363                if (vms.lastmsg > -1 && !vms.starting) {
05364                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
05365                   if (cmd == ERROR_LOCK_PATH) {
05366                      res = cmd;
05367                      goto out;
05368                   }
05369                } else
05370                   cmd = ast_play_and_wait(chan, "vm-sorry");
05371                cmd = 't';
05372                break;
05373             case '4': /* Dialout */
05374                if (!ast_strlen_zero(vmu->dialout)) {
05375                   cmd = dialout(chan, vmu, NULL, vmu->dialout);
05376                   if (cmd == 9) {
05377                      silentexit = 1;
05378                      goto out;
05379                   }
05380                }
05381                else 
05382                   cmd = ast_play_and_wait(chan, "vm-sorry");
05383                cmd = 't';
05384                break;
05385 
05386             case '5': /* Leave VoiceMail */
05387                if (ast_test_flag(vmu, VM_SVMAIL)) {
05388                   cmd = forward_message(chan, vmu->context, vms.curdir, vms.curmsg, vmu, vmfmts, 1, record_gain);
05389                   if (cmd == ERROR_LOCK_PATH) {
05390                      res = cmd;
05391                      goto out;
05392                   }
05393                } else
05394                   cmd = ast_play_and_wait(chan,"vm-sorry");
05395                cmd='t';
05396                break;
05397                
05398             case '*': /* Return to main menu */
05399                cmd = 't';
05400                break;
05401 
05402             default:
05403                cmd = 0;
05404                if (!vms.starting) {
05405                   cmd = ast_play_and_wait(chan, "vm-toreply");
05406                }
05407                if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
05408                   cmd = ast_play_and_wait(chan, "vm-tocallback");
05409                }
05410                if (!cmd && !vms.starting) {
05411                   cmd = ast_play_and_wait(chan, "vm-tohearenv");
05412                }
05413                if (!ast_strlen_zero(vmu->dialout) && !cmd) {
05414                   cmd = ast_play_and_wait(chan, "vm-tomakecall");
05415                }
05416                if (ast_test_flag(vmu, VM_SVMAIL) && !cmd)
05417                   cmd=ast_play_and_wait(chan, "vm-leavemsg");
05418                if (!cmd)
05419                   cmd = ast_play_and_wait(chan, "vm-starmain");
05420                if (!cmd)
05421                   cmd = ast_waitfordigit(chan,6000);
05422                if (!cmd)
05423                   vms.repeats++;
05424                if (vms.repeats > 3)
05425                   cmd = 't';
05426             }
05427          }
05428          if (cmd == 't') {
05429             cmd = 0;
05430             vms.repeats = 0;
05431          }
05432          break;
05433       case '4':
05434          if (vms.curmsg) {
05435             vms.curmsg--;
05436             cmd = play_message(chan, vmu, &vms);
05437          } else {
05438             cmd = ast_play_and_wait(chan, "vm-nomore");
05439          }
05440          break;
05441       case '6':
05442          if (vms.curmsg < vms.lastmsg) {
05443             vms.curmsg++;
05444             cmd = play_message(chan, vmu, &vms);
05445          } else {
05446             cmd = ast_play_and_wait(chan, "vm-nomore");
05447          }
05448          break;
05449       case '7':
05450          vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
05451          if (useadsi)
05452             adsi_delete(chan, &vms);
05453          if (vms.deleted[vms.curmsg]) 
05454             cmd = ast_play_and_wait(chan, "vm-deleted");
05455          else
05456             cmd = ast_play_and_wait(chan, "vm-undeleted");
05457          if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
05458             if (vms.curmsg < vms.lastmsg) {
05459                vms.curmsg++;
05460                cmd = play_message(chan, vmu, &vms);
05461             } else {
05462                cmd = ast_play_and_wait(chan, "vm-nomore");
05463             }
05464          }
05465          break;
05466    
05467       case '8':
05468          if (vms.lastmsg > -1) {
05469             cmd = forward_message(chan, vmu->context, vms.curdir, vms.curmsg, vmu, vmfmts, 0, record_gain);
05470             if (cmd == ERROR_LOCK_PATH) {
05471                res = cmd;
05472                goto out;
05473             }
05474          } else
05475             cmd = ast_play_and_wait(chan, "vm-nomore");
05476          break;
05477       case '9':
05478          if (useadsi)
05479             adsi_folders(chan, 1, "Save to folder...");
05480          cmd = get_folder2(chan, "vm-savefolder", 1);
05481          box = 0; /* Shut up compiler */
05482          if (cmd == '#') {
05483             cmd = 0;
05484             break;
05485          } else if (cmd > 0) {
05486             box = cmd = cmd - '0';
05487             cmd = save_to_folder(vmu, vms.curdir, vms.curmsg, vmu->context, vms.username, cmd);
05488             if (cmd == ERROR_LOCK_PATH) {
05489                res = cmd;
05490                goto out;
05491             } else if (!cmd) {
05492                vms.deleted[vms.curmsg] = 1;
05493             } else {
05494                vms.deleted[vms.curmsg] = 0;
05495                vms.heard[vms.curmsg] = 0;
05496             }
05497          }
05498          make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
05499          if (useadsi)
05500             adsi_message(chan, &vms);
05501          snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
05502          if (!cmd) {
05503             cmd = ast_play_and_wait(chan, "vm-message");
05504             if (!cmd)
05505                cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
05506             if (!cmd)
05507                cmd = ast_play_and_wait(chan, "vm-savedto");
05508             if (!cmd)
05509                cmd = vm_play_folder_name(chan, vms.fn);
05510          } else {
05511             cmd = ast_play_and_wait(chan, "vm-mailboxfull");
05512          }
05513          if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
05514             if (vms.curmsg < vms.lastmsg) {
05515                vms.curmsg++;
05516                cmd = play_message(chan, vmu, &vms);
05517             } else {
05518                cmd = ast_play_and_wait(chan, "vm-nomore");
05519             }
05520          }
05521          break;
05522       case '*':
05523          if (!vms.starting) {
05524             cmd = ast_play_and_wait(chan, "vm-onefor");
05525             if (!cmd)
05526                cmd = vm_play_folder_name(chan, vms.vmbox);
05527             if (!cmd)
05528                cmd = ast_play_and_wait(chan, "vm-opts");
05529             if (!cmd)
05530                cmd = vm_instructions(chan, &vms, 1);
05531          } else
05532             cmd = 0;
05533          break;
05534       case '0':
05535          cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
05536          if (useadsi)
05537             adsi_status(chan, &vms);
05538          break;
05539       default: /* Nothing */
05540          cmd = vm_instructions(chan, &vms, 0);
05541          break;
05542       }
05543    }
05544    if ((cmd == 't') || (cmd == '#')) {
05545       /* Timeout */
05546       res = 0;
05547    } else {
05548       /* Hangup */
05549       res = -1;
05550    }
05551 
05552 out:
05553    if (res > -1) {
05554       ast_stopstream(chan);
05555       adsi_goodbye(chan);
05556       if (valid) {
05557          if (silentexit)
05558             res = ast_play_and_wait(chan, "vm-dialout");
05559          else 
05560             res = ast_play_and_wait(chan, "vm-goodbye");
05561          if (res > 0)
05562             res = 0;
05563       }
05564       if (useadsi)
05565          adsi_unload_session(chan);
05566    }
05567    if (vmu)
05568       close_mailbox(&vms, vmu);
05569    if (valid) {
05570       snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
05571       manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
05572       run_externnotify(vmu->context, vmu->mailbox);
05573    }
05574    if (vmu)
05575       free_user(vmu);
05576    if (vms.deleted)
05577       free(vms.deleted);
05578    if (vms.heard)
05579       free(vms.heard);
05580    LOCAL_USER_REMOVE(u);
05581 
05582    return res;
05583 }

static int vm_forwardoptions ( struct ast_channel chan,
struct ast_vm_user vmu,
char *  curdir,
int  curmsg,
char *  vmfts,
char *  context,
signed char  record_gain 
) [static]

Definition at line 3282 of file app_voicemail.c.

References ast_channel_setoption(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), and ast_waitfordigit().

Referenced by forward_message().

03284 {
03285    int cmd = 0;
03286    int retries = 0;
03287    int duration = 0;
03288    signed char zero_gain = 0;
03289 
03290    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
03291       if (cmd)
03292          retries = 0;
03293       switch (cmd) {
03294       case '1': 
03295          /* prepend a message to the current message and return */
03296       {
03297          char file[200];
03298          snprintf(file, sizeof(file), "%s/msg%04d", curdir, curmsg);
03299          if (record_gain)
03300             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
03301          cmd = ast_play_and_prepend(chan, NULL, file, 0, vmfmts, &duration, 1, silencethreshold, maxsilence);
03302          if (record_gain)
03303             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
03304          break;
03305       }
03306       case '2': 
03307          cmd = 't';
03308          break;
03309       case '*':
03310          cmd = '*';
03311          break;
03312       default: 
03313          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
03314             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
03315          if (!cmd)
03316             cmd = ast_play_and_wait(chan,"vm-starmain");
03317             /* "press star to return to the main menu" */
03318          if (!cmd)
03319             cmd = ast_waitfordigit(chan,6000);
03320          if (!cmd)
03321             retries++;
03322          if (retries > 3)
03323             cmd = 't';
03324        }
03325    }
03326    if (cmd == 't' || cmd == 'S')
03327       cmd = 0;
03328    return cmd;
03329 }

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

Definition at line 4634 of file app_voicemail.c.

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

Referenced by vm_execmain().

04635 {
04636    int res = 0;
04637    /* Play instructions and wait for new command */
04638    while (!res) {
04639       if (vms->starting) {
04640          if (vms->lastmsg > -1) {
04641             res = ast_play_and_wait(chan, "vm-onefor");
04642             if (!res)
04643                res = vm_play_folder_name(chan, vms->vmbox);
04644          }
04645          if (!res)
04646             res = ast_play_and_wait(chan, "vm-opts");
04647       } else {
04648          if (vms->curmsg)
04649             res = ast_play_and_wait(chan, "vm-prev");
04650          if (!res && !skipadvanced)
04651             res = ast_play_and_wait(chan, "vm-advopts");
04652          if (!res)
04653             res = ast_play_and_wait(chan, "vm-repeat");
04654          if (!res && (vms->curmsg != vms->lastmsg))
04655             res = ast_play_and_wait(chan, "vm-next");
04656          if (!res) {
04657             if (!vms->deleted[vms->curmsg])
04658                res = ast_play_and_wait(chan, "vm-delete");
04659             else
04660                res = ast_play_and_wait(chan, "vm-undelete");
04661             if (!res)
04662                res = ast_play_and_wait(chan, "vm-toforward");
04663             if (!res)
04664                res = ast_play_and_wait(chan, "vm-savemessage");
04665          }
04666       }
04667       if (!res)
04668          res = ast_play_and_wait(chan, "vm-helpexit");
04669       if (!res)
04670          res = ast_waitfordigit(chan, 6000);
04671       if (!res) {
04672          vms->repeats++;
04673          if (vms->repeats > 2) {
04674             res = 't';
04675          }
04676       }
04677    }
04678    return res;
04679 }

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

Definition at line 4604 of file app_voicemail.c.

References ast_channel::language, 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_pt(), vm_intro_pt_BR(), and vm_intro_se().

Referenced by vm_execmain().

04605 {
04606    /* Play voicemail intro - syntax is different for different languages */
04607    if (!strcasecmp(chan->language, "de")) {  /* GERMAN syntax */
04608       return vm_intro_de(chan, vms);
04609    } else if (!strcasecmp(chan->language, "es")) { /* SPANISH syntax */
04610       return vm_intro_es(chan, vms);
04611    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN syntax */
04612       return vm_intro_it(chan, vms);
04613    } else if (!strcasecmp(chan->language, "fr")) { /* FRENCH syntax */
04614       return vm_intro_fr(chan, vms);
04615    } else if (!strcasecmp(chan->language, "nl")) { /* DUTCH syntax */
04616       return vm_intro_nl(chan, vms);
04617    } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE syntax */
04618       return vm_intro_pt(chan, vms);
04619    } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */
04620       return vm_intro_pt_BR(chan, vms);
04621    } else if (!strcasecmp(chan->language, "cz")) { /* CZECH syntax */
04622       return vm_intro_cz(chan, vms);
04623    } else if (!strcasecmp(chan->language, "gr")) { /* GREEK syntax */
04624       return vm_intro_gr(chan, vms);
04625    } else if (!strcasecmp(chan->language, "se")) { /* SWEDISH syntax */
04626       return vm_intro_se(chan, vms);
04627    } else if (!strcasecmp(chan->language, "no")) { /* NORWEGIAN syntax */
04628       return vm_intro_no(chan, vms);
04629    } else {             /* Default to ENGLISH */
04630       return vm_intro_en(chan, vms);
04631    }
04632 }

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

Definition at line 4544 of file app_voicemail.c.

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

Referenced by vm_intro().

04545 {
04546    int res;
04547    res = ast_play_and_wait(chan, "vm-youhave");
04548    if (!res) {
04549       if (vms->newmessages) {
04550          if (vms->newmessages == 1) {
04551             res = ast_play_and_wait(chan, "digits/jednu");
04552          } else {
04553             res = say_and_wait(chan, vms->newmessages, chan->language);
04554          }
04555          if (!res) {
04556             if ((vms->newmessages == 1))
04557                res = ast_play_and_wait(chan, "vm-novou");
04558             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
04559                res = ast_play_and_wait(chan, "vm-nove");
04560             if (vms->newmessages > 4)
04561                res = ast_play_and_wait(chan, "vm-novych");
04562          }
04563          if (vms->oldmessages && !res)
04564             res = ast_play_and_wait(chan, "vm-and");
04565          else if (!res) {
04566             if ((vms->newmessages == 1))
04567                res = ast_play_and_wait(chan, "vm-zpravu");
04568             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
04569                res = ast_play_and_wait(chan, "vm-zpravy");
04570             if (vms->newmessages > 4)
04571                res = ast_play_and_wait(chan, "vm-zprav");
04572          }
04573       }
04574       if (!res && vms->oldmessages) {
04575          res = say_and_wait(chan, vms->oldmessages, chan->language);
04576          if (!res) {
04577             if ((vms->oldmessages == 1))
04578                res = ast_play_and_wait(chan, "vm-starou");
04579             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
04580                res = ast_play_and_wait(chan, "vm-stare");
04581             if (vms->oldmessages > 4)
04582                res = ast_play_and_wait(chan, "vm-starych");
04583          }
04584          if (!res) {
04585             if ((vms->oldmessages == 1))
04586                res = ast_play_and_wait(chan, "vm-zpravu");
04587             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
04588                res = ast_play_and_wait(chan, "vm-zpravy");
04589             if (vms->oldmessages > 4)
04590                res = ast_play_and_wait(chan, "vm-zprav");
04591          }
04592       }
04593       if (!res) {
04594          if (!vms->oldmessages && !vms->newmessages) {
04595             res = ast_play_and_wait(chan, "vm-no");
04596             if (!res)
04597                res = ast_play_and_wait(chan, "vm-zpravy");
04598          }
04599       }
04600    }
04601    return res;
04602 }

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

Definition at line 4237 of file app_voicemail.c.

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

Referenced by vm_intro().

04238 {
04239    /* Introduce messages they have */
04240    int res;
04241    res = ast_play_and_wait(chan, "vm-youhave");
04242    if (!res) {
04243       if (vms->newmessages) {
04244          if ((vms->newmessages == 1))
04245             res = ast_play_and_wait(chan, "digits/1F");
04246          else
04247             res = say_and_wait(chan, vms->newmessages, chan->language);
04248          if (!res)
04249             res = ast_play_and_wait(chan, "vm-INBOX");
04250          if (vms->oldmessages && !res)
04251             res = ast_play_and_wait(chan, "vm-and");
04252          else if (!res) {
04253             if ((vms->newmessages == 1))
04254                res = ast_play_and_wait(chan, "vm-message");
04255             else
04256                res = ast_play_and_wait(chan, "vm-messages");
04257          }
04258             
04259       }
04260       if (!res && vms->oldmessages) {
04261          if (vms->oldmessages == 1)
04262             res = ast_play_and_wait(chan, "digits/1F");
04263          else
04264             res = say_and_wait(chan, vms->oldmessages, chan->language);
04265          if (!res)
04266             res = ast_play_and_wait(chan, "vm-Old");
04267          if (!res) {
04268             if (vms->oldmessages == 1)
04269                res = ast_play_and_wait(chan, "vm-message");
04270             else
04271                res = ast_play_and_wait(chan, "vm-messages");
04272          }
04273       }
04274       if (!res) {
04275          if (!vms->oldmessages && !vms->newmessages) {
04276             res = ast_play_and_wait(chan, "vm-no");
04277             if (!res)
04278                res = ast_play_and_wait(chan, "vm-messages");
04279          }
04280       }
04281    }
04282    return res;
04283 }

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

Definition at line 4071 of file app_voicemail.c.

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

Referenced by vm_intro().

04072 {
04073    /* Introduce messages they have */
04074    int res;
04075    res = ast_play_and_wait(chan, "vm-youhave");
04076    if (!res) {
04077       if (vms->newmessages) {
04078          res = say_and_wait(chan, vms->newmessages, chan->language);
04079          if (!res)
04080             res = ast_play_and_wait(chan, "vm-INBOX");
04081          if (vms->oldmessages && !res)
04082             res = ast_play_and_wait(chan, "vm-and");
04083          else if (!res) {
04084             if ((vms->newmessages == 1))
04085                res = ast_play_and_wait(chan, "vm-message");
04086             else
04087                res = ast_play_and_wait(chan, "vm-messages");
04088          }
04089             
04090       }
04091       if (!res && vms->oldmessages) {
04092          res = say_and_wait(chan, vms->oldmessages, chan->language);
04093          if (!res)
04094             res = ast_play_and_wait(chan, "vm-Old");
04095          if (!res) {
04096             if (vms->oldmessages == 1)
04097                res = ast_play_and_wait(chan, "vm-message");
04098             else
04099                res = ast_play_and_wait(chan, "vm-messages");
04100          }
04101       }
04102       if (!res) {
04103          if (!vms->oldmessages && !vms->newmessages) {
04104             res = ast_play_and_wait(chan, "vm-no");
04105             if (!res)
04106                res = ast_play_and_wait(chan, "vm-messages");
04107          }
04108       }
04109    }
04110    return res;
04111 }

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

Definition at line 4286 of file app_voicemail.c.

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

Referenced by vm_intro().

04287 {
04288    /* Introduce messages they have */
04289    int res;
04290    if (!vms->oldmessages && !vms->newmessages) {
04291       res = ast_play_and_wait(chan, "vm-youhaveno");
04292       if (!res)
04293          res = ast_play_and_wait(chan, "vm-messages");
04294    } else {
04295       res = ast_play_and_wait(chan, "vm-youhave");
04296    }
04297    if (!res) {
04298       if (vms->newmessages) {
04299          if (!res) {
04300             if ((vms->newmessages == 1)) {
04301                res = ast_play_and_wait(chan, "digits/1M");
04302                if (!res)
04303                   res = ast_play_and_wait(chan, "vm-message");
04304                if (!res)
04305                   res = ast_play_and_wait(chan, "vm-INBOXs");
04306             } else {
04307                res = say_and_wait(chan, vms->newmessages, chan->language);
04308                if (!res)
04309                   res = ast_play_and_wait(chan, "vm-messages");
04310                if (!res)
04311                   res = ast_play_and_wait(chan, "vm-INBOX");
04312             }
04313          }
04314          if (vms->oldmessages && !res)
04315             res = ast_play_and_wait(chan, "vm-and");
04316       }
04317       if (vms->oldmessages) {
04318          if (!res) {
04319             if (vms->oldmessages == 1) {
04320                res = ast_play_and_wait(chan, "digits/1M");
04321                if (!res)
04322                   res = ast_play_and_wait(chan, "vm-message");
04323                if (!res)
04324                   res = ast_play_and_wait(chan, "vm-Olds");
04325             } else {
04326                res = say_and_wait(chan, vms->oldmessages, chan->language);
04327                if (!res)
04328                   res = ast_play_and_wait(chan, "vm-messages");
04329                if (!res)
04330                   res = ast_play_and_wait(chan, "vm-Old");
04331             }
04332          }
04333       }
04334    }
04335 return res;
04336 }

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

Definition at line 4387 of file app_voicemail.c.

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

Referenced by vm_intro().

04388 {
04389    /* Introduce messages they have */
04390    int res;
04391    res = ast_play_and_wait(chan, "vm-youhave");
04392    if (!res) {
04393       if (vms->newmessages) {
04394          res = say_and_wait(chan, vms->newmessages, chan->language);
04395          if (!res)
04396             res = ast_play_and_wait(chan, "vm-INBOX");
04397          if (vms->oldmessages && !res)
04398             res = ast_play_and_wait(chan, "vm-and");
04399          else if (!res) {
04400             if ((vms->newmessages == 1))
04401                res = ast_play_and_wait(chan, "vm-message");
04402             else
04403                res = ast_play_and_wait(chan, "vm-messages");
04404          }
04405             
04406       }
04407       if (!res && vms->oldmessages) {
04408          res = say_and_wait(chan, vms->oldmessages, chan->language);
04409          if (!res) {
04410             if (vms->oldmessages == 1)
04411                res = ast_play_and_wait(chan, "vm-message");
04412             else
04413                res = ast_play_and_wait(chan, "vm-messages");
04414          }
04415          if (!res)
04416             res = ast_play_and_wait(chan, "vm-Old");
04417       }
04418       if (!res) {
04419          if (!vms->oldmessages && !vms->newmessages) {
04420             res = ast_play_and_wait(chan, "vm-no");
04421             if (!res)
04422                res = ast_play_and_wait(chan, "vm-messages");
04423          }
04424       }
04425    }
04426    return res;
04427 }

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

Definition at line 4033 of file app_voicemail.c.

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

Referenced by vm_intro().

04034 {
04035    int res = 0;
04036 
04037    if (vms->newmessages) {
04038       res = ast_play_and_wait(chan, "vm-youhave");
04039       if (!res) 
04040          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
04041       if (!res) {
04042          if ((vms->newmessages == 1)) {
04043             res = ast_play_and_wait(chan, "vm-INBOX");
04044             if (!res)
04045                res = ast_play_and_wait(chan, "vm-message");
04046          } else {
04047             res = ast_play_and_wait(chan, "vm-INBOXs");
04048             if (!res)
04049                res = ast_play_and_wait(chan, "vm-messages");
04050          }
04051       }    
04052    } else if (vms->oldmessages){
04053       res = ast_play_and_wait(chan, "vm-youhave");
04054       if (!res)
04055          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
04056       if ((vms->oldmessages == 1)){
04057          res = ast_play_and_wait(chan, "vm-Old");
04058          if (!res)
04059             res = ast_play_and_wait(chan, "vm-message");
04060       } else {
04061          res = ast_play_and_wait(chan, "vm-Olds");
04062          if (!res)
04063             res = ast_play_and_wait(chan, "vm-messages");
04064       }
04065     } else if (!vms->oldmessages && !vms->newmessages) 
04066          res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
04067     return res;
04068 }

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

Definition at line 4114 of file app_voicemail.c.

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

Referenced by vm_intro().

04115 {
04116    /* Introduce messages they have */
04117    int res;
04118    if (!vms->oldmessages && !vms->newmessages)
04119       res = ast_play_and_wait(chan, "vm-no") ||
04120          ast_play_and_wait(chan, "vm-message");
04121    else
04122       res = ast_play_and_wait(chan, "vm-youhave");
04123    if (!res && vms->newmessages) {
04124       res = (vms->newmessages == 1) ?
04125          ast_play_and_wait(chan, "digits/un") ||
04126          ast_play_and_wait(chan, "vm-nuovo") ||
04127          ast_play_and_wait(chan, "vm-message") :
04128          /* 2 or more new messages */
04129          say_and_wait(chan, vms->newmessages, chan->language) ||
04130          ast_play_and_wait(chan, "vm-nuovi") ||
04131          ast_play_and_wait(chan, "vm-messages");
04132       if (!res && vms->oldmessages)
04133          res = ast_play_and_wait(chan, "vm-and");
04134    }
04135    if (!res && vms->oldmessages) {
04136       res = (vms->oldmessages == 1) ?
04137          ast_play_and_wait(chan, "digits/un") ||
04138          ast_play_and_wait(chan, "vm-vecchio") ||
04139          ast_play_and_wait(chan, "vm-message") :
04140          /* 2 or more old messages */
04141          say_and_wait(chan, vms->oldmessages, chan->language) ||
04142          ast_play_and_wait(chan, "vm-vecchi") ||
04143          ast_play_and_wait(chan, "vm-messages");
04144    }
04145    return res;
04146 }

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

Definition at line 4430 of file app_voicemail.c.

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

Referenced by vm_intro().

04431 {
04432    /* Introduce messages they have */
04433    int res;
04434    res = ast_play_and_wait(chan, "vm-youhave");
04435    if (!res) {
04436       if (vms->newmessages) {
04437          res = say_and_wait(chan, vms->newmessages, chan->language);
04438          if (!res) {
04439             if (vms->newmessages == 1)
04440                res = ast_play_and_wait(chan, "vm-INBOXs");
04441             else
04442                res = ast_play_and_wait(chan, "vm-INBOX");
04443          }
04444          if (vms->oldmessages && !res)
04445             res = ast_play_and_wait(chan, "vm-and");
04446          else if (!res) {
04447             if ((vms->newmessages == 1))
04448                res = ast_play_and_wait(chan, "vm-message");
04449             else
04450                res = ast_play_and_wait(chan, "vm-messages");
04451          }
04452             
04453       }
04454       if (!res && vms->oldmessages) {
04455          res = say_and_wait(chan, vms->oldmessages, chan->language);
04456          if (!res) {
04457             if (vms->oldmessages == 1)
04458                res = ast_play_and_wait(chan, "vm-Olds");
04459             else
04460                res = ast_play_and_wait(chan, "vm-Old");
04461          }
04462          if (!res) {
04463             if (vms->oldmessages == 1)
04464                res = ast_play_and_wait(chan, "vm-message");
04465             else
04466                res = ast_play_and_wait(chan, "vm-messages");
04467          }
04468       }
04469       if (!res) {
04470          if (!vms->oldmessages && !vms->newmessages) {
04471             res = ast_play_and_wait(chan, "vm-no");
04472             if (!res)
04473                res = ast_play_and_wait(chan, "vm-messages");
04474          }
04475       }
04476    }
04477    return res;
04478 }

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

Definition at line 4193 of file app_voicemail.c.

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

Referenced by vm_intro().

04194 {
04195         /* Introduce messages they have */
04196         int res;
04197 
04198    res = ast_play_and_wait(chan, "vm-youhave");
04199    if (res)
04200       return res;
04201 
04202         if (!vms->oldmessages && !vms->newmessages) {
04203       res = ast_play_and_wait(chan, "vm-no");
04204       res = res ? res : ast_play_and_wait(chan, "vm-messages");
04205       return res;
04206         }
04207 
04208    if (vms->newmessages) {
04209       if ((vms->newmessages == 1)) {
04210          res = ast_play_and_wait(chan, "digits/1");
04211          res = res ? res : ast_play_and_wait(chan, "vm-ny");
04212          res = res ? res : ast_play_and_wait(chan, "vm-message");
04213       } else {
04214          res = say_and_wait(chan, vms->newmessages, chan->language);
04215          res = res ? res : ast_play_and_wait(chan, "vm-nye");
04216          res = res ? res : ast_play_and_wait(chan, "vm-messages");
04217       }
04218       if (!res && vms->oldmessages)
04219          res = ast_play_and_wait(chan, "vm-and");
04220    }
04221    if (!res && vms->oldmessages) {
04222       if (vms->oldmessages == 1) {
04223          res = ast_play_and_wait(chan, "digits/1");
04224          res = res ? res : ast_play_and_wait(chan, "vm-gamel");
04225          res = res ? res : ast_play_and_wait(chan, "vm-message");
04226       } else {
04227          res = say_and_wait(chan, vms->oldmessages, chan->language);
04228          res = res ? res : ast_play_and_wait(chan, "vm-gamle");
04229          res = res ? res : ast_play_and_wait(chan, "vm-messages");
04230       }
04231    }
04232 
04233    return res;
04234 }

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

Definition at line 4481 of file app_voicemail.c.

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

Referenced by vm_intro().

04482 {
04483    /* Introduce messages they have */
04484    int res;
04485    res = ast_play_and_wait(chan, "vm-youhave");
04486    if (!res) {
04487       if (vms->newmessages) {
04488          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
04489          if (!res) {
04490             if ((vms->newmessages == 1)) {
04491                res = ast_play_and_wait(chan, "vm-message");
04492                if (!res)
04493                   res = ast_play_and_wait(chan, "vm-INBOXs");
04494             } else {
04495                res = ast_play_and_wait(chan, "vm-messages");
04496                if (!res)
04497                   res = ast_play_and_wait(chan, "vm-INBOX");
04498             }
04499          }
04500          if (vms->oldmessages && !res)
04501             res = ast_play_and_wait(chan, "vm-and");
04502       }
04503       if (!res && vms->oldmessages) {
04504          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
04505          if (!res) {
04506             if (vms->oldmessages == 1) {
04507                res = ast_play_and_wait(chan, "vm-message");
04508                if (!res)
04509                   res = ast_play_and_wait(chan, "vm-Olds");
04510             } else {
04511                res = ast_play_and_wait(chan, "vm-messages");
04512                if (!res)
04513                   res = ast_play_and_wait(chan, "vm-Old");
04514             }
04515          }
04516       }
04517       if (!res) {
04518          if (!vms->oldmessages && !vms->newmessages) {
04519             res = ast_play_and_wait(chan, "vm-no");
04520             if (!res)
04521                res = ast_play_and_wait(chan, "vm-messages");
04522          }
04523       }
04524    }
04525    return res;
04526 }

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

Definition at line 4339 of file app_voicemail.c.

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

Referenced by vm_intro().

04339                                                                          {
04340     /* Introduce messages they have */
04341     int res;
04342     if (!vms->oldmessages && !vms->newmessages) {
04343         res = ast_play_and_wait(chan, "vm-nomessages");
04344         return res;
04345     }
04346     else {
04347         res = ast_play_and_wait(chan, "vm-youhave");
04348     }
04349     if (vms->newmessages) {
04350         if (!res)
04351             res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
04352         if ((vms->newmessages == 1)) {
04353             if (!res)
04354                 res = ast_play_and_wait(chan, "vm-message");
04355             if (!res)
04356                 res = ast_play_and_wait(chan, "vm-INBOXs");
04357         }
04358         else {
04359             if (!res)
04360                 res = ast_play_and_wait(chan, "vm-messages");
04361             if (!res)
04362                 res = ast_play_and_wait(chan, "vm-INBOX");
04363         }
04364         if (vms->oldmessages && !res)
04365             res = ast_play_and_wait(chan, "vm-and");
04366     }
04367     if (vms->oldmessages) {
04368         if (!res)
04369             res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
04370         if (vms->oldmessages == 1) {
04371             if (!res)
04372                 res = ast_play_and_wait(chan, "vm-message");
04373             if (!res)
04374                 res = ast_play_and_wait(chan, "vm-Olds");
04375         }
04376         else {
04377             if (!res)
04378                 res = ast_play_and_wait(chan, "vm-messages");
04379             if (!res)
04380                 res = ast_play_and_wait(chan, "vm-Old");
04381         }
04382     }
04383     return res;
04384 }

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

Definition at line 4149 of file app_voicemail.c.

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

Referenced by vm_intro().

04150 {
04151         /* Introduce messages they have */
04152         int res;
04153 
04154    res = ast_play_and_wait(chan, "vm-youhave");
04155    if (res)
04156       return res;
04157 
04158         if (!vms->oldmessages && !vms->newmessages) {
04159       res = ast_play_and_wait(chan, "vm-no");
04160       res = res ? res : ast_play_and_wait(chan, "vm-messages");
04161       return res;
04162         }
04163 
04164    if (vms->newmessages) {
04165       if ((vms->newmessages == 1)) {
04166          res = ast_play_and_wait(chan, "digits/ett");
04167          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
04168          res = res ? res : ast_play_and_wait(chan, "vm-message");
04169       } else {
04170          res = say_and_wait(chan, vms->newmessages, chan->language);
04171          res = res ? res : ast_play_and_wait(chan, "vm-nya");
04172          res = res ? res : ast_play_and_wait(chan, "vm-messages");
04173       }
04174       if (!res && vms->oldmessages)
04175          res = ast_play_and_wait(chan, "vm-and");
04176    }
04177    if (!res && vms->oldmessages) {
04178       if (vms->oldmessages == 1) {
04179          res = ast_play_and_wait(chan, "digits/ett");
04180          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
04181          res = res ? res : ast_play_and_wait(chan, "vm-message");
04182       } else {
04183          res = say_and_wait(chan, vms->oldmessages, chan->language);
04184          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
04185          res = res ? res : ast_play_and_wait(chan, "vm-messages");
04186       }
04187    }
04188 
04189    return res;
04190 }

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

Definition at line 822 of file app_voicemail.c.

References ast_lock_path(), and AST_LOCK_TIMEOUT.

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

00823 {
00824    switch (ast_lock_path(path)) {
00825    case AST_LOCK_TIMEOUT:
00826       return -1;
00827    default:
00828       return 0;
00829    }
00830 }

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 4681 of file app_voicemail.c.

References adsi_available(), ADSI_COMM_PAGE, adsi_display(), ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, adsi_set_line(), adsi_transmit_message(), adsi_voice_mode(), ast_log(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_flag, LOG_NOTICE, play_record_review(), vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, and VM_FORCENAME.

Referenced by vm_execmain().

04682 {
04683    int cmd = 0;
04684    int duration = 0;
04685    int tries = 0;
04686    char newpassword[80] = "";
04687    char newpassword2[80] = "";
04688    char prefile[256]="";
04689    unsigned char buf[256];
04690    int bytes=0;
04691 
04692    if (adsi_available(chan)) {
04693       bytes += adsi_logo(buf + bytes);
04694       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
04695       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
04696       bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04697       bytes += adsi_voice_mode(buf + bytes, 0);
04698       adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04699    }
04700 
04701    /* First, have the user change their password 
04702       so they won't get here again */
04703    for (;;) {
04704       newpassword[1] = '\0';
04705       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
04706       if (cmd == '#')
04707          newpassword[0] = '\0';
04708       if (cmd < 0 || cmd == 't' || cmd == '#')
04709          return cmd;
04710       cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
04711       if (cmd < 0 || cmd == 't' || cmd == '#')
04712          return cmd;
04713       newpassword2[1] = '\0';
04714       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
04715       if (cmd == '#')
04716          newpassword2[0] = '\0';
04717       if (cmd < 0 || cmd == 't' || cmd == '#')
04718          return cmd;
04719       cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
04720       if (cmd < 0 || cmd == 't' || cmd == '#')
04721          return cmd;
04722       if (!strcmp(newpassword, newpassword2))
04723          break;
04724       ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
04725       cmd = ast_play_and_wait(chan, "vm-mismatch");
04726       if (++tries == 3)
04727          return -1;
04728    }
04729    if (ast_strlen_zero(ext_pass_cmd)) 
04730       vm_change_password(vmu,newpassword);
04731    else 
04732       vm_change_password_shell(vmu,newpassword);
04733    
04734    cmd = ast_play_and_wait(chan,"vm-passchanged");
04735 
04736    /* If forcename is set, have the user record their name */  
04737    if (ast_test_flag(vmu, VM_FORCENAME)) {
04738       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
04739       cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
04740       if (cmd < 0 || cmd == 't' || cmd == '#')
04741          return cmd;
04742    }
04743 
04744    /* If forcegreetings is set, have the user record their greetings */
04745    if (ast_test_flag(vmu, VM_FORCEGREET)) {
04746       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
04747       cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
04748       if (cmd < 0 || cmd == 't' || cmd == '#')
04749          return cmd;
04750       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
04751       cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
04752       if (cmd < 0 || cmd == 't' || cmd == '#')
04753          return cmd;
04754    }
04755 
04756    return cmd;
04757 }

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 4759 of file app_voicemail.c.

References adsi_available(), ADSI_COMM_PAGE, adsi_display(), ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, adsi_set_line(), adsi_transmit_message(), adsi_voice_mode(), ast_log(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_waitfordigit(), ast_vm_user::context, LOG_DEBUG, LOG_NOTICE, ast_vm_user::password, play_record_review(), vm_state::username, vm_change_password(), vm_change_password_shell(), and vm_tempgreeting().

Referenced by vm_execmain().

04760 {
04761    int cmd = 0;
04762    int retries = 0;
04763    int duration = 0;
04764    char newpassword[80] = "";
04765    char newpassword2[80] = "";
04766    char prefile[256]="";
04767    unsigned char buf[256];
04768    int bytes=0;
04769 
04770    if (adsi_available(chan))
04771    {
04772       bytes += adsi_logo(buf + bytes);
04773       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
04774       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
04775       bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04776       bytes += adsi_voice_mode(buf + bytes, 0);
04777       adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04778    }
04779    while ((cmd >= 0) && (cmd != 't')) {
04780       if (cmd)
04781          retries = 0;
04782       switch (cmd) {
04783       case '1':
04784          snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
04785          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
04786          break;
04787       case '2': 
04788          snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
04789          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
04790          break;
04791       case '3': 
04792          snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
04793          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
04794          break;
04795       case '4': 
04796          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
04797          break;
04798       case '5':
04799          if (vmu->password[0] == '-') {
04800             cmd = ast_play_and_wait(chan, "vm-no");
04801             break;
04802          }
04803          newpassword[1] = '\0';
04804          newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
04805          if (cmd == '#')
04806             newpassword[0] = '\0';
04807          else {
04808             if (cmd < 0)
04809                break;
04810             if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
04811                break;
04812             }
04813          }
04814          newpassword2[1] = '\0';
04815          newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
04816          if (cmd == '#')
04817             newpassword2[0] = '\0';
04818          else {
04819             if (cmd < 0)
04820                break;
04821 
04822             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#"))) {
04823                break;
04824             }
04825          }
04826          if (strcmp(newpassword, newpassword2)) {
04827             ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
04828             cmd = ast_play_and_wait(chan, "vm-mismatch");
04829             break;
04830          }
04831          if (ast_strlen_zero(ext_pass_cmd)) 
04832             vm_change_password(vmu,newpassword);
04833          else 
04834             vm_change_password_shell(vmu,newpassword);
04835          ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
04836          cmd = ast_play_and_wait(chan,"vm-passchanged");
04837          break;
04838       case '*': 
04839          cmd = 't';
04840          break;
04841       default: 
04842          cmd = ast_play_and_wait(chan,"vm-options");
04843          if (!cmd)
04844             cmd = ast_waitfordigit(chan,6000);
04845          if (!cmd)
04846             retries++;
04847          if (retries > 3)
04848             cmd = 't';
04849        }
04850    }
04851    if (cmd == 't')
04852       cmd = 0;
04853    return cmd;
04854 }

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

Definition at line 4002 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, and vm_play_folder_name_gr().

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

04003 {
04004    int cmd;
04005 
04006    if (!strcasecmp(chan->language, "it") || !strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "fr") || !strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) { /* Italian, Spanish, French or Portuguese syntax */
04007       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
04008       if (cmd)
04009          return cmd;
04010       return ast_play_and_wait(chan, mbox);
04011    } else if (!strcasecmp(chan->language, "gr")){
04012       return vm_play_folder_name_gr(chan, mbox);
04013    } else {  /* Default English */
04014       cmd = ast_play_and_wait(chan, mbox);
04015       if (cmd)
04016          return cmd;
04017       return ast_play_and_wait(chan, "vm-messages"); /* "messages */
04018    }
04019 }

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

Definition at line 3980 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

03981 {
03982    int cmd;
03983    char *buf;
03984 
03985    buf = alloca(strlen(mbox)+2); 
03986    strcpy(buf, mbox);
03987    strcat(buf,"s");
03988 
03989    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
03990       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
03991       if (cmd)
03992       return cmd;
03993       return ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
03994    } else {
03995       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
03996       if (cmd)
03997          return cmd;
03998       return ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
03999    }
04000 }

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 4856 of file app_voicemail.c.

References adsi_available(), ADSI_COMM_PAGE, adsi_display(), ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, adsi_set_line(), adsi_transmit_message(), adsi_voice_mode(), ast_fileexists(), ast_play_and_wait(), ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, play_record_review(), RETRIEVE, and vm_state::username.

Referenced by vm_options().

04857 {
04858    int cmd = 0;
04859    int retries = 0;
04860    int duration = 0;
04861    char prefile[256]="";
04862    unsigned char buf[256];
04863    int bytes=0;
04864 
04865    if (adsi_available(chan))
04866    {
04867       bytes += adsi_logo(buf + bytes);
04868       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
04869       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
04870       bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04871       bytes += adsi_voice_mode(buf + bytes, 0);
04872       adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04873    }
04874    snprintf(prefile,sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
04875    while((cmd >= 0) && (cmd != 't')) {
04876       if (cmd)
04877          retries = 0;
04878       RETRIEVE(prefile, -1);
04879       if (ast_fileexists(prefile, NULL, NULL) > 0) {
04880          switch (cmd) {
04881          case '1':
04882             cmd = play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
04883             break;
04884          case '2':
04885             DELETE(prefile, -1, prefile);
04886             ast_play_and_wait(chan,"vm-tempremoved");
04887             cmd = 't';  
04888             break;
04889          case '*': 
04890             cmd = 't';
04891             break;
04892          default:
04893             if (ast_fileexists(prefile, NULL, NULL) > 0) {
04894                cmd = ast_play_and_wait(chan,"vm-tempgreeting2");
04895             } else {
04896                cmd = ast_play_and_wait(chan,"vm-tempgreeting");
04897             } if (!cmd) {
04898                cmd = ast_waitfordigit(chan,6000);
04899             } if (!cmd) {
04900                retries++;
04901             } if (retries > 3) {
04902                cmd = 't';
04903             }
04904          }
04905       } else {
04906          play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
04907          cmd = 't';  
04908       }
04909       DISPOSE(prefile, -1);
04910    }
04911    if (cmd == 't')
04912       cmd = 0;
04913    return cmd;
04914 }

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

Definition at line 5765 of file app_voicemail.c.

References ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_vm_user::context, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, pbx_builtin_setvar_helper(), s, strsep(), user, and vm_authenticate().

Referenced by load_module().

05766 {
05767    struct localuser *u;
05768    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
05769    struct ast_vm_user vmus;
05770    char *options = NULL;
05771    int silent = 0, skipuser = 0;
05772    int res = -1;
05773 
05774    LOCAL_USER_ADD(u);
05775    
05776    if (s) {
05777       s = ast_strdupa(s);
05778       if (!s) {
05779          ast_log(LOG_ERROR, "Out of memory\n");
05780          return -1;
05781       }
05782       user = strsep(&s, "|");
05783       options = strsep(&s, "|");
05784       if (user) {
05785          s = user;
05786          user = strsep(&s, "@");
05787          context = strsep(&s, "");
05788          if (!ast_strlen_zero(user))
05789             skipuser++;
05790          ast_copy_string(mailbox, user, sizeof(mailbox));
05791       }
05792    }
05793 
05794    if (options) {
05795       silent = (strchr(options, 's')) != NULL;
05796    }
05797 
05798    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
05799       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
05800       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
05801       ast_play_and_wait(chan, "auth-thankyou");
05802       res = 0;
05803    }
05804 
05805    LOCAL_USER_REMOVE(u);
05806    return res;
05807 }

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

Definition at line 3628 of file app_voicemail.c.

References ast_control_streamfile().

03629 {
03630    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
03631 }

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

Definition at line 3618 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_log(), ast_streamfile(), ast_waitstream(), ast_channel::language, and LOG_WARNING.

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

03619 {
03620    int res;
03621    if ((res = ast_streamfile(chan, file, chan->language))) 
03622       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
03623    if (!res)
03624       res = ast_waitstream(chan, AST_DIGIT_ANY);
03625    return res;
03626 }


Variable Documentation

char* addesc = "Comedian Mail" [static]

Definition at line 297 of file app_voicemail.c.

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

Definition at line 417 of file app_voicemail.c.

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

Definition at line 418 of file app_voicemail.c.

int adsiver = 1 [static]

Definition at line 419 of file app_voicemail.c.

char* app = "VoiceMail" [static]

Definition at line 370 of file app_voicemail.c.

char* app2 = "VoiceMailMain" [static]

Definition at line 373 of file app_voicemail.c.

char* app3 = "MailboxExists" [static]

Definition at line 375 of file app_voicemail.c.

char* app4 = "VMAuthenticate" [static]

Definition at line 376 of file app_voicemail.c.

char callcontext[AST_MAX_CONTEXT] [static]

Definition at line 402 of file app_voicemail.c.

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

Definition at line 415 of file app_voicemail.c.

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static]

Definition at line 405 of file app_voicemail.c.

char* descrip_vm [static]

Definition at line 302 of file app_voicemail.c.

char* descrip_vm_box_exists [static]

Definition at line 345 of file app_voicemail.c.

char* descrip_vmain [static]

Definition at line 329 of file app_voicemail.c.

char* descrip_vmauthenticate [static]

Definition at line 359 of file app_voicemail.c.

char dialcontext[AST_MAX_CONTEXT] [static]

Definition at line 401 of file app_voicemail.c.

Referenced by directory_exec().

char* emailbody = NULL [static]

Definition at line 408 of file app_voicemail.c.

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

Definition at line 420 of file app_voicemail.c.

char* emailsubject = NULL [static]

Definition at line 409 of file app_voicemail.c.

char emailtitle[100] [static]

Definition at line 414 of file app_voicemail.c.

char exitcontext[AST_MAX_CONTEXT] [static]

Definition at line 403 of file app_voicemail.c.

Referenced by conf_run().

char ext_pass_cmd[128] [static]

Definition at line 293 of file app_voicemail.c.

char externnotify[160] [static]

Definition at line 388 of file app_voicemail.c.

char fromstring[100] [static]

Definition at line 412 of file app_voicemail.c.

struct ast_flags globalflags = {0} [static]

Definition at line 397 of file app_voicemail.c.

LOCAL_USER_DECL

Definition at line 424 of file app_voicemail.c.

char mailcmd[160] [static]

Definition at line 387 of file app_voicemail.c.

int maxgreet [static]

Definition at line 393 of file app_voicemail.c.

int maxlogins [static]

Definition at line 395 of file app_voicemail.c.

int maxmsg [static]

Definition at line 384 of file app_voicemail.c.

int maxsilence [static]

Definition at line 383 of file app_voicemail.c.

Referenced by waitforsilence_exec().

char* pagerbody = NULL [static]

Definition at line 410 of file app_voicemail.c.

char pagerfromstring[100] [static]

Definition at line 413 of file app_voicemail.c.

char* pagersubject = NULL [static]

Definition at line 411 of file app_voicemail.c.

int saydurationminfo [static]

Definition at line 399 of file app_voicemail.c.

char serveremail[80] [static]

Definition at line 386 of file app_voicemail.c.

struct ast_cli_entry show_voicemail_users_cli [static]

Initial value:

   { { "show", "voicemail", "users", NULL },
   handle_show_voicemail_users, "List defined voicemail boxes",
   show_voicemail_users_help, complete_show_voicemail_users }

Definition at line 5920 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char show_voicemail_users_help[] [static]

Initial value:

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

Definition at line 5809 of file app_voicemail.c.

struct ast_cli_entry show_voicemail_zones_cli [static]

Initial value:

   { { "show", "voicemail", "zones", NULL },
   handle_show_voicemail_zones, "List zone message formats",
   show_voicemail_zones_help, NULL }

Definition at line 5925 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char show_voicemail_zones_help[] [static]

Initial value:

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

Definition at line 5813 of file app_voicemail.c.

int silencethreshold = 128 [static]

Definition at line 385 of file app_voicemail.c.

int skipms [static]

Definition at line 394 of file app_voicemail.c.

Referenced by controlplayback_exec(), and handle_controlstreamfile().

STANDARD_LOCAL_USER

Definition at line 422 of file app_voicemail.c.

char* synopsis_vm [static]

Initial value:

"Leave a Voicemail message"

Definition at line 299 of file app_voicemail.c.

char* synopsis_vm_box_exists [static]

Initial value:

"Check to see if Voicemail mailbox exists"

Definition at line 342 of file app_voicemail.c.

char* synopsis_vmain [static]

Initial value:

"Check Voicemail messages"

Definition at line 326 of file app_voicemail.c.

char* synopsis_vmauthenticate [static]

Initial value:

"Authenticate with Voicemail passwords"

Definition at line 356 of file app_voicemail.c.

char* tdesc = "Comedian Mail (Voicemail System)" [static]

Definition at line 295 of file app_voicemail.c.

struct ast_vm_user* users

Definition at line 379 of file app_voicemail.c.

Referenced by append_mailbox(), complete_show_voicemail_users(), find_user(), handle_show_voicemail_users(), load_config(), and reset_user_pw().

struct ast_vm_user* usersl

Definition at line 380 of file app_voicemail.c.

Referenced by append_mailbox(), and load_config().

enum { ... } vm_option_args

enum { ... } vm_option_flags

char VM_SPOOL_DIR[AST_CONFIG_MAX_PATH] [static]

Definition at line 291 of file app_voicemail.c.

char vmfmts[80] [static]

Definition at line 390 of file app_voicemail.c.

int vmmaxmessage [static]

Definition at line 392 of file app_voicemail.c.

int vmminmessage [static]

Definition at line 391 of file app_voicemail.c.

struct vm_zone* zones = NULL

Definition at line 381 of file app_voicemail.c.

Referenced by handle_show_voicemail_zones(), load_config(), play_message_datetime(), sendmail(), and sendpage().

struct vm_zone* zonesl = NULL

Definition at line 382 of file app_voicemail.c.

Referenced by load_config().


Generated on Fri Sep 29 11:13:01 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7