Wed Oct 28 15:48:18 2009

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 CHUNKSIZE   65536
#define COMMAND_TIMEOUT   5000
#define COPY(a, b, c, d, e, f, g, h)   (copy_file(g,h));
#define DELETE(a, b, c)   (vm_delete(c))
#define DISPOSE(a, b)
#define 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, char *dir)
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)
static char * quote (const char *from, char *to, size_t len)
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 *vmfmts, char *context, signed char record_gain, long *duration)
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_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)"
struct ast_vm_userusers
struct 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
struct vm_zonezones = NULL
struct 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 83 of file app_voicemail.c.

Referenced by load_config().

#define BASELINELEN   72

Definition at line 95 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 96 of file app_voicemail.c.

#define BASEMAXINLINE   256

Definition at line 96 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 80 of file app_voicemail.c.

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

Referenced by copy_message(), and save_to_folder().

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

#define DISPOSE ( a,
 ) 

#define eol   "\r\n"

Definition at line 97 of file app_voicemail.c.

Referenced by base_encode(), and ochar().

#define ERROR_LOCK_PATH   -100

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

#define INTRO   "vm-intro"

Definition at line 89 of file app_voicemail.c.

Referenced by leave_voicemail(), and play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 99 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 100 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 91 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

Definition at line 92 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 285 of file app_voicemail.c.

Referenced by close_mailbox(), and resequence_mailbox().

#define RETRIEVE ( a,
 ) 

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

Definition at line 87 of file app_voicemail.c.

Referenced by load_config().

#define STORE ( a,
b,
c,
 ) 

Definition at line 283 of file app_voicemail.c.

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

#define VM_ALLOCED   (1 << 13)

Definition at line 115 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 113 of file app_voicemail.c.

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

#define VM_DELETE   (1 << 12)

Definition at line 114 of file app_voicemail.c.

Referenced by apply_option(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 112 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

Definition at line 106 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 110 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 109 of file app_voicemail.c.

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

#define VM_OPERATOR   (1 << 1)

Definition at line 103 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 111 of file app_voicemail.c.

Referenced by load_config(), and sendmail().

#define VM_REVIEW   (1 << 0)

Definition at line 102 of file app_voicemail.c.

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

#define VM_SAYCID   (1 << 2)

Definition at line 104 of file app_voicemail.c.

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

#define VM_SAYDURATION   (1 << 5)

Definition at line 107 of file app_voicemail.c.

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

#define VM_SEARCH   (1 << 14)

Definition at line 116 of file app_voicemail.c.

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

#define VM_SKIPAFTERCMD   (1 << 6)

Definition at line 108 of file app_voicemail.c.

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

Definition at line 105 of file app_voicemail.c.

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

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 82 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 120 of file app_voicemail.c.

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

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_ARRAY_SIZE 

Definition at line 129 of file app_voicemail.c.

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


Function Documentation

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

Definition at line 2948 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().

02949 {
02950    int x;
02951    if (!adsi_available(chan))
02952       return;
02953    x = adsi_load_session(chan, adsifdn, adsiver, 1);
02954    if (x < 0)
02955       return;
02956    if (!x) {
02957       if (adsi_load_vmail(chan, useadsi)) {
02958          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
02959          return;
02960       }
02961    } else
02962       *useadsi = 1;
02963 }

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

Definition at line 3135 of file app_voicemail.c.

References adsi_available(), ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, adsi_set_keys(), adsi_transmit_message(), adsi_voice_mode(), vm_state::curmsg, vm_state::deleted, keys, and vm_state::lastmsg.

Referenced by vm_execmain().

03136 {
03137    int bytes=0;
03138    unsigned char buf[256];
03139    unsigned char keys[8];
03140 
03141    int x;
03142 
03143    if (!adsi_available(chan))
03144       return;
03145 
03146    /* New meaning for keys */
03147    for (x=0;x<5;x++)
03148       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
03149 
03150    keys[6] = 0x0;
03151    keys[7] = 0x0;
03152 
03153    if (!vms->curmsg) {
03154       /* No prev key, provide "Folder" instead */
03155       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03156    }
03157    if (vms->curmsg >= vms->lastmsg) {
03158       /* If last message ... */
03159       if (vms->curmsg) {
03160          /* but not only message, provide "Folder" instead */
03161          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03162       } else {
03163          /* Otherwise if only message, leave blank */
03164          keys[3] = 1;
03165       }
03166    }
03167 
03168    /* If deleted, show "undeleted" */
03169    if (vms->deleted[vms->curmsg]) 
03170       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
03171 
03172    /* Except "Exit" */
03173    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
03174    bytes += adsi_set_keys(buf + bytes, keys);
03175    bytes += adsi_voice_mode(buf + bytes, 0);
03176 
03177    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03178 }

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

Definition at line 3013 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().

03014 {
03015    unsigned char buf[256];
03016    int bytes=0;
03017    unsigned char keys[8];
03018    int x,y;
03019 
03020    if (!adsi_available(chan))
03021       return;
03022 
03023    for (x=0;x<5;x++) {
03024       y = ADSI_KEY_APPS + 12 + start + x;
03025       if (y > ADSI_KEY_APPS + 12 + 4)
03026          y = 0;
03027       keys[x] = ADSI_KEY_SKT | y;
03028    }
03029    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
03030    keys[6] = 0;
03031    keys[7] = 0;
03032 
03033    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
03034    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
03035    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03036    bytes += adsi_set_keys(buf + bytes, keys);
03037    bytes += adsi_voice_mode(buf + bytes, 0);
03038 
03039    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03040 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

Definition at line 3283 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().

03284 {
03285    unsigned char buf[256];
03286    int bytes=0;
03287 
03288    if (!adsi_available(chan))
03289       return;
03290    bytes += adsi_logo(buf + bytes);
03291    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
03292    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
03293    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03294    bytes += adsi_voice_mode(buf + bytes, 0);
03295 
03296    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03297 }

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

Definition at line 2819 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().

02820 {
02821    unsigned char buf[256];
02822    int bytes=0;
02823    int x;
02824    char num[5];
02825 
02826    *useadsi = 0;
02827    bytes += adsi_data_mode(buf + bytes);
02828    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02829 
02830    bytes = 0;
02831    bytes += adsi_logo(buf);
02832    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
02833 #ifdef DISPLAY
02834    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
02835 #endif
02836    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02837    bytes += adsi_data_mode(buf + bytes);
02838    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02839 
02840    if (adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
02841       bytes = 0;
02842       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
02843       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
02844       bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02845       bytes += adsi_voice_mode(buf + bytes, 0);
02846       adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02847       return 0;
02848    }
02849 
02850 #ifdef DISPLAY
02851    /* Add a dot */
02852    bytes = 0;
02853    bytes += adsi_logo(buf);
02854    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
02855    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
02856    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02857    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02858 #endif
02859    bytes = 0;
02860    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
02861    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
02862    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
02863    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
02864    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
02865    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
02866    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
02867 
02868 #ifdef DISPLAY
02869    /* Add another dot */
02870    bytes = 0;
02871    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
02872    bytes += adsi_voice_mode(buf + bytes, 0);
02873 
02874    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02875    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02876 #endif
02877 
02878    bytes = 0;
02879    /* These buttons we load but don't use yet */
02880    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
02881    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
02882    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
02883    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
02884    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
02885    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
02886    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
02887 
02888 #ifdef DISPLAY
02889    /* Add another dot */
02890    bytes = 0;
02891    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
02892    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02893    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02894 #endif
02895 
02896    bytes = 0;
02897    for (x=0;x<5;x++) {
02898       snprintf(num, sizeof(num), "%d", x);
02899       bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
02900    }
02901    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
02902    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
02903 
02904 #ifdef DISPLAY
02905    /* Add another dot */
02906    bytes = 0;
02907    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
02908    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02909    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02910 #endif
02911 
02912    if (adsi_end_download(chan)) {
02913       bytes = 0;
02914       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
02915       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
02916       bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02917       bytes += adsi_voice_mode(buf + bytes, 0);
02918       adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02919       return 0;
02920    }
02921    bytes = 0;
02922    bytes += adsi_download_disconnect(buf + bytes);
02923    bytes += adsi_voice_mode(buf + bytes, 0);
02924    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
02925 
02926    ast_log(LOG_DEBUG, "Done downloading scripts...\n");
02927 
02928 #ifdef DISPLAY
02929    /* Add last dot */
02930    bytes = 0;
02931    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
02932    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02933 #endif
02934    ast_log(LOG_DEBUG, "Restarting session...\n");
02935 
02936    bytes = 0;
02937    /* Load the session now */
02938    if (adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
02939       *useadsi = 1;
02940       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
02941    } else
02942       bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
02943 
02944    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02945    return 0;
02946 }

static void adsi_login ( struct ast_channel chan  )  [static]

Definition at line 2965 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().

02966 {
02967    unsigned char buf[256];
02968    int bytes=0;
02969    unsigned char keys[8];
02970    int x;
02971    if (!adsi_available(chan))
02972       return;
02973 
02974    for (x=0;x<8;x++)
02975       keys[x] = 0;
02976    /* Set one key for next */
02977    keys[3] = ADSI_KEY_APPS + 3;
02978 
02979    bytes += adsi_logo(buf + bytes);
02980    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
02981    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
02982    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
02983    bytes += adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
02984    bytes += adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
02985    bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
02986    bytes += adsi_set_keys(buf + bytes, keys);
02987    bytes += adsi_voice_mode(buf + bytes, 0);
02988    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
02989 }

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

Definition at line 2811 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().

02812 {
02813    int bytes = 0;
02814    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
02815    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
02816    return bytes;
02817 }

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

Definition at line 3042 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(), ast_callerid_parse(), ast_strlen_zero(), vm_state::curbox, vm_state::curmsg, vm_state::deleted, vm_state::fn, keys, vm_state::lastmsg, name, and strsep().

Referenced by play_message(), and vm_execmain().

03043 {
03044    int bytes=0;
03045    unsigned char buf[256]; 
03046    char buf1[256], buf2[256];
03047    char fn2[PATH_MAX];
03048 
03049    char cid[256]="";
03050    char *val;
03051    char *name, *num;
03052    char datetime[21]="";
03053    FILE *f;
03054 
03055    unsigned char keys[8];
03056 
03057    int x;
03058 
03059    if (!adsi_available(chan))
03060       return;
03061 
03062    /* Retrieve important info */
03063    snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
03064    f = fopen(fn2, "r");
03065    if (f) {
03066       while (!feof(f)) {   
03067          fgets((char *)buf, sizeof(buf), f);
03068          if (!feof(f)) {
03069             char *stringp=NULL;
03070             stringp = (char *)buf;
03071             strsep(&stringp, "=");
03072             val = strsep(&stringp, "=");
03073             if (!ast_strlen_zero(val)) {
03074                if (!strcmp((char *)buf, "callerid"))
03075                   ast_copy_string(cid, val, sizeof(cid));
03076                if (!strcmp((char *)buf, "origdate"))
03077                   ast_copy_string(datetime, val, sizeof(datetime));
03078             }
03079          }
03080       }
03081       fclose(f);
03082    }
03083    /* New meaning for keys */
03084    for (x=0;x<5;x++)
03085       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
03086    keys[6] = 0x0;
03087    keys[7] = 0x0;
03088 
03089    if (!vms->curmsg) {
03090       /* No prev key, provide "Folder" instead */
03091       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03092    }
03093    if (vms->curmsg >= vms->lastmsg) {
03094       /* If last message ... */
03095       if (vms->curmsg) {
03096          /* but not only message, provide "Folder" instead */
03097          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03098          bytes += adsi_voice_mode(buf + bytes, 0);
03099 
03100       } else {
03101          /* Otherwise if only message, leave blank */
03102          keys[3] = 1;
03103       }
03104    }
03105 
03106    if (!ast_strlen_zero(cid)) {
03107       ast_callerid_parse(cid, &name, &num);
03108       if (!name)
03109          name = num;
03110    } else
03111       name = "Unknown Caller";
03112 
03113    /* If deleted, show "undeleted" */
03114 
03115    if (vms->deleted[vms->curmsg])
03116       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
03117 
03118    /* Except "Exit" */
03119    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
03120    snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
03121       strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
03122    snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
03123 
03124    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03125    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03126    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
03127    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
03128    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03129    bytes += adsi_set_keys(buf + bytes, keys);
03130    bytes += adsi_voice_mode(buf + bytes, 0);
03131 
03132    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03133 }

static void adsi_password ( struct ast_channel chan  )  [static]

Definition at line 2991 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().

02992 {
02993    unsigned char buf[256];
02994    int bytes=0;
02995    unsigned char keys[8];
02996    int x;
02997    if (!adsi_available(chan))
02998       return;
02999 
03000    for (x=0;x<8;x++)
03001       keys[x] = 0;
03002    /* Set one key for next */
03003    keys[3] = ADSI_KEY_APPS + 3;
03004 
03005    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03006    bytes += adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
03007    bytes += adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
03008    bytes += adsi_set_keys(buf + bytes, keys);
03009    bytes += adsi_voice_mode(buf + bytes, 0);
03010    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03011 }

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

Definition at line 3180 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().

03181 {
03182    unsigned char buf[256] = "";
03183    char buf1[256] = "", buf2[256] = "";
03184    int bytes=0;
03185    unsigned char keys[8];
03186    int x;
03187 
03188    char *newm = (vms->newmessages == 1) ? "message" : "messages";
03189    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
03190    if (!adsi_available(chan))
03191       return;
03192    if (vms->newmessages) {
03193       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
03194       if (vms->oldmessages) {
03195          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
03196          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
03197       } else {
03198          snprintf(buf2, sizeof(buf2), "%s.", newm);
03199       }
03200    } else if (vms->oldmessages) {
03201       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
03202       snprintf(buf2, sizeof(buf2), "%s.", oldm);
03203    } else {
03204       strcpy(buf1, "You have no messages.");
03205       buf2[0] = ' ';
03206       buf2[1] = '\0';
03207    }
03208    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03209    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03210    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03211 
03212    for (x=0;x<6;x++)
03213       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03214    keys[6] = 0;
03215    keys[7] = 0;
03216 
03217    /* Don't let them listen if there are none */
03218    if (vms->lastmsg < 0)
03219       keys[0] = 1;
03220    bytes += adsi_set_keys(buf + bytes, keys);
03221 
03222    bytes += adsi_voice_mode(buf + bytes, 0);
03223 
03224    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03225 }

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

Definition at line 3227 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().

03228 {
03229    unsigned char buf[256] = "";
03230    char buf1[256] = "", buf2[256] = "";
03231    int bytes=0;
03232    unsigned char keys[8];
03233    int x;
03234 
03235    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
03236 
03237    if (!adsi_available(chan))
03238       return;
03239 
03240    /* Original command keys */
03241    for (x=0;x<6;x++)
03242       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03243 
03244    keys[6] = 0;
03245    keys[7] = 0;
03246 
03247    if ((vms->lastmsg + 1) < 1)
03248       keys[0] = 0;
03249 
03250    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
03251       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
03252 
03253    if (vms->lastmsg + 1)
03254       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
03255    else
03256       strcpy(buf2, "no messages.");
03257    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03258    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03259    bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
03260    bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03261    bytes += adsi_set_keys(buf + bytes, keys);
03262 
03263    bytes += adsi_voice_mode(buf + bytes, 0);
03264 
03265    adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03266    
03267 }

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

References ast_callerid_parse(), ast_config_destroy(), ast_config_load(), ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_variable_retrieve(), ast_verbose(), ast_waitfordigit(), ast_vm_user::callback, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, 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(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, VERBOSE_PREFIX_3, and wait_file().

Referenced by vm_execmain().

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

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

Definition at line 5694 of file app_voicemail.c.

References apply_options(), ast_strdupa, ast_vm_user::context, ast_vm_user::email, ast_vm_user::fullname, ast_vm_user::mailbox, malloc, ast_vm_user::next, ast_vm_user::pager, ast_vm_user::password, populate_defaults(), s, and strsep().

Referenced by load_config().

05695 {
05696    /* Assumes lock is already held */
05697    char *tmp;
05698    char *stringp;
05699    char *s;
05700    struct ast_vm_user *vmu;
05701 
05702    tmp = ast_strdupa(data);
05703 
05704    vmu = malloc(sizeof(struct ast_vm_user));
05705    if (vmu) {
05706       memset(vmu, 0, sizeof(struct ast_vm_user));
05707       ast_copy_string(vmu->context, context, sizeof(vmu->context));
05708       ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
05709 
05710       populate_defaults(vmu);
05711 
05712       stringp = tmp;
05713       if ((s = strsep(&stringp, ","))) 
05714          ast_copy_string(vmu->password, s, sizeof(vmu->password));
05715       if (stringp && (s = strsep(&stringp, ","))) 
05716          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
05717       if (stringp && (s = strsep(&stringp, ","))) 
05718          ast_copy_string(vmu->email, s, sizeof(vmu->email));
05719       if (stringp && (s = strsep(&stringp, ","))) 
05720          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
05721       if (stringp && (s = strsep(&stringp, ","))) 
05722          apply_options(vmu, s);
05723       
05724       vmu->next = NULL;
05725       if (usersl)
05726          usersl->next = vmu;
05727       else
05728          users = vmu;
05729       usersl = vmu;
05730    }
05731    return 0;
05732 }

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

Definition at line 440 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().

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

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

Definition at line 511 of file app_voicemail.c.

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

Referenced by append_mailbox(), and apply_option().

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

AST_APP_OPTIONS ( vm_app_options   ) 

AST_MUTEX_DEFINE_STATIC ( vmlock   ) 

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

Definition at line 1566 of file app_voicemail.c.

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

Referenced by sendmail().

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

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

Definition at line 495 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().

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

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

Definition at line 3961 of file app_voicemail.c.

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

Referenced by vm_execmain().

03962 {
03963    int x, nummsg;
03964    int res = 0;
03965 
03966    if (vms->lastmsg <= -1)
03967       goto done;
03968 
03969    /* Get the deleted messages fixed */ 
03970    if (vm_lock_path(vms->curdir))
03971       return ERROR_LOCK_PATH;
03972    
03973    vms->curmsg = -1; 
03974    for (x = 0; x < vmu->maxmsg; x++) { 
03975       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
03976          /* Save this message.  It's not in INBOX or hasn't been heard */ 
03977          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
03978          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
03979             break;
03980          vms->curmsg++; 
03981          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
03982          if (strcmp(vms->fn, vms->fn2)) { 
03983             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
03984          } 
03985       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
03986          /* Move to old folder before deleting */ 
03987          res = save_to_folder(vmu, vms->curdir, x, vmu->context, vms->username, 1);
03988          if (res == ERROR_LOCK_PATH) {
03989             /* If save failed do not delete the message */
03990             vms->deleted[x] = 0;
03991             vms->heard[x] = 0;
03992             --x;
03993          } 
03994       } 
03995    } 
03996 
03997    /* Delete ALL remaining messages */
03998    nummsg = x - 1;
03999    for (x = vms->curmsg + 1; x <= nummsg; x++) {
04000       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
04001       if (EXISTS(vms->curdir, x, vms->fn, NULL))
04002          DELETE(vms->curdir, x, vms->fn);
04003    }
04004    ast_unlock_path(vms->curdir);
04005 
04006 done:
04007    if (vms->deleted)
04008       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
04009    if (vms->heard)
04010       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
04011 
04012    return 0;
04013 }

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

Definition at line 5899 of file app_voicemail.c.

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

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

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

Definition at line 1418 of file app_voicemail.c.

References ast_log(), LOG_WARNING, and VOICEMAIL_FILE_MODE.

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

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

Definition at line 1468 of file app_voicemail.c.

References ast_filecopy(), and copy().

01469 {
01470    char frompath2[PATH_MAX], topath2[PATH_MAX];
01471    ast_filecopy(frompath, topath, NULL);
01472    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
01473    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
01474    copy(frompath2, topath2);
01475 }

static int copy_message ( struct ast_channel chan,
struct ast_vm_user vmu,
int  imbox,
int  msgnum,
long  duration,
struct ast_vm_user recip,
char *  fmt,
char *  dir 
) [static]

Definition at line 2351 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 forward_message(), and leave_voicemail().

02352 {
02353    char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
02354    char *frombox = mbox(imbox);
02355    int recipmsgnum;
02356 
02357    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
02358 
02359    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
02360    
02361    if (!dir)
02362       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
02363    else
02364       ast_copy_string(fromdir, dir, sizeof(fromdir));
02365 
02366    make_file(frompath, sizeof(frompath), fromdir, msgnum);
02367 
02368    if (vm_lock_path(todir))
02369       return ERROR_LOCK_PATH;
02370 
02371    recipmsgnum = 0;
02372    do {
02373       make_file(topath, sizeof(topath), todir, recipmsgnum);
02374       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
02375          break;
02376       recipmsgnum++;
02377    } while (recipmsgnum < recip->maxmsg);
02378    if (recipmsgnum < recip->maxmsg) {
02379       COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
02380    } else {
02381       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
02382    }
02383    ast_unlock_path(todir);
02384    notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
02385    
02386    return 0;
02387 }

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

Definition at line 1385 of file app_voicemail.c.

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

Referenced by leave_voicemail(), and open_mailbox().

01386 {
01387    /* Find all .txt files - even if they are not in sequence from 0000 */
01388 
01389    int vmcount = 0;
01390    DIR *vmdir = NULL;
01391    struct dirent *vment = NULL;
01392 
01393    if (vm_lock_path(dir))
01394       return ERROR_LOCK_PATH;
01395 
01396    if ((vmdir = opendir(dir))) {
01397       while ((vment = readdir(vmdir))) {
01398          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
01399             vmcount++;
01400       }
01401       closedir(vmdir);
01402    }
01403    ast_unlock_path(dir);
01404    
01405    return vmcount;
01406 }

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:
-1 on failure, 0 on success.

Definition at line 790 of file app_voicemail.c.

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

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

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

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 6435 of file app_voicemail.c.

06436 {
06437    return tdesc;
06438 }

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

Definition at line 6440 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().

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

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

Definition at line 576 of file app_voicemail.c.

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

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

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

Definition at line 525 of file app_voicemail.c.

References apply_option(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), ast_vm_user::context, ast_vm_user::email, free, ast_vm_user::fullname, ast_vm_user::mailbox, malloc, ast_variable::name, ast_variable::next, ast_vm_user::pager, ast_vm_user::password, populate_defaults(), ast_vm_user::uniqueid, ast_variable::value, var, VM_ALLOCED, and VM_SEARCH.

Referenced by find_user().

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

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

References ast_clear_flag, ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_channel::context, copy_message(), ast_channel::exten, find_user(), free_user(), ast_channel::language, leave_voicemail(), LOG_WARNING, ast_vm_user::mailbox, ast_vm_user::next, pbx_exec(), pbx_findapp(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, s, strsep(), username, VM_DIRECFORWARD, and vm_forwardoptions().

Referenced by vm_execmain().

03491 {
03492    char username[70]="";
03493    int res = 0, cmd = 0;
03494    struct ast_vm_user *receiver = NULL, *extensions = NULL, *vmtmp = NULL, *vmfree;
03495    char *stringp, *s;
03496    int saved_messages = 0, found = 0;
03497    int valid_extensions = 0;
03498    
03499    while (!res && !valid_extensions) {
03500       int use_directory = 0;
03501       if(ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
03502          int done = 0;
03503          int retries = 0;
03504          cmd=0;
03505          while((cmd >= 0) && !done ){
03506             if (cmd)
03507                retries = 0;
03508             switch (cmd) {
03509             case '1': 
03510                use_directory = 0;
03511                done = 1;
03512                break;
03513             case '2': 
03514                use_directory = 1;
03515                done=1;
03516                break;
03517             case '*': 
03518                cmd = 't';
03519                done = 1;
03520                break;
03521             default: 
03522                /* Press 1 to enter an extension press 2 to use the directory */
03523                cmd = ast_play_and_wait(chan,"vm-forward");
03524                if (!cmd)
03525                   cmd = ast_waitfordigit(chan,3000);
03526                if (!cmd)
03527                   retries++;
03528                if (retries > 3)
03529                {
03530                   cmd = 't';
03531                   done = 1;
03532                }
03533                
03534              }
03535          }
03536          if( cmd<0 || cmd=='t' )
03537             break;
03538       }
03539       
03540       if (use_directory) {
03541          /* use app_directory */
03542          
03543          char old_context[sizeof(chan->context)];
03544          char old_exten[sizeof(chan->exten)];
03545          int old_priority;
03546          struct ast_app* app;
03547 
03548          
03549          app = pbx_findapp("Directory");
03550          if (app) {
03551             /* make backup copies */
03552             char vmcontext[256];
03553             memcpy(old_context, chan->context, sizeof(chan->context));
03554             memcpy(old_exten, chan->exten, sizeof(chan->exten));
03555             old_priority = chan->priority;
03556             
03557             /* call the the Directory, changes the channel */
03558             sprintf(vmcontext, "%s||v", context ? context : "default");
03559             res = pbx_exec(chan, app, vmcontext, 1);
03560             
03561             ast_copy_string(username, chan->exten, sizeof(username));
03562             
03563             /* restore the old context, exten, and priority */
03564             memcpy(chan->context, old_context, sizeof(chan->context));
03565             memcpy(chan->exten, old_exten, sizeof(chan->exten));
03566             chan->priority = old_priority;
03567             
03568          } else {
03569             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
03570             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
03571          }
03572       } else   {
03573          /* Ask for an extension */
03574          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
03575          if (res)
03576             break;
03577          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
03578             break;
03579       }
03580       
03581       /* start all over if no username */
03582       if (ast_strlen_zero(username))
03583          continue;
03584       stringp = username;
03585       s = strsep(&stringp, "*");
03586       /* start optimistic */
03587       valid_extensions = 1;
03588       while (s) {
03589          /* Don't forward to ourselves.  find_user is going to malloc since we have a NULL as first argument */
03590          if (strcmp(s,sender->mailbox) && (receiver = find_user(NULL, context, s))) {
03591             if (!extensions)
03592                vmtmp = extensions = receiver;
03593             else {
03594                vmtmp->next = receiver;
03595                vmtmp = receiver;
03596             }
03597             found++;
03598          } else {
03599             valid_extensions = 0;
03600             break;
03601          }
03602          s = strsep(&stringp, "*");
03603       }
03604       /* break from the loop of reading the extensions */
03605       if (valid_extensions)
03606          break;
03607       /* "I am sorry, that's not a valid extension.  Please try again." */
03608       res = ast_play_and_wait(chan, "pbx-invalid");
03609    }
03610    /* check if we're clear to proceed */
03611    if (!extensions || !valid_extensions)
03612       return res;
03613    vmtmp = extensions;
03614    if (flag==1) {
03615       struct leave_vm_options leave_options;
03616       char mailbox[AST_MAX_EXTENSION * 2 + 2];
03617       snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
03618 
03619       /* Send VoiceMail */
03620       memset(&leave_options, 0, sizeof(leave_options));
03621       leave_options.record_gain = record_gain;
03622       cmd = leave_voicemail(chan, mailbox, &leave_options);
03623    } else {
03624       /* Forward VoiceMail */
03625       long duration = 0;
03626       RETRIEVE(dir, curmsg);
03627       cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, context, record_gain, &duration);
03628       if (!cmd) {
03629          while (!res && vmtmp) {
03630             copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir);
03631    
03632             saved_messages++;
03633             vmfree = vmtmp;
03634             vmtmp = vmtmp->next;
03635             free_user(vmfree);
03636          }
03637          extensions = NULL;
03638          if (saved_messages > 0) {
03639             /* give confirmation that the message was saved */
03640             /* commented out since we can't forward batches yet
03641             if (saved_messages == 1)
03642                res = ast_play_and_wait(chan, "vm-message");
03643             else
03644                res = ast_play_and_wait(chan, "vm-messages");
03645             if (!res)
03646                res = ast_play_and_wait(chan, "vm-saved"); */
03647             res = ast_play_and_wait(chan, "vm-msgsaved");
03648          }  
03649       }
03650    }
03651 
03652    /* If anything failed above, we still have this list to free */
03653    while (extensions) {
03654       vmfree = extensions;
03655       extensions = extensions->next;
03656       free_user(vmfree);
03657    }
03658    return res ? res : cmd;
03659 }

static void free_user ( struct ast_vm_user vmu  )  [static]

Definition at line 2013 of file app_voicemail.c.

References ast_test_flag, free, and VM_ALLOCED.

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

02014 {
02015    if (ast_test_flag(vmu, VM_ALLOCED))
02016       free(vmu);
02017 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 2019 of file app_voicemail.c.

References free.

02020 {
02021    free(z);
02022 }

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

Definition at line 1956 of file app_voicemail.c.

References t.

Referenced by leave_voicemail(), and tds_log().

01957 {
01958    struct tm tm;
01959    time_t t;
01960    t = time(0);
01961    localtime_r(&t,&tm);
01962    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
01963 }

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

Definition at line 3303 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().

03304 {
03305    int x;
03306    int d;
03307    char fn[PATH_MAX];
03308    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
03309    if (d)
03310       return d;
03311    for (x = start; x< 5; x++) {  /* For all folders */
03312       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
03313          return d;
03314       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
03315       if (d)
03316          return d;
03317       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
03318       d = vm_play_folder_name(chan, fn);
03319       if (d)
03320          return d;
03321       d = ast_waitfordigit(chan, 500);
03322       if (d)
03323          return d;
03324    }
03325    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
03326    if (d)
03327       return d;
03328    d = ast_waitfordigit(chan, 4000);
03329    return d;
03330 }

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

Definition at line 3332 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

03333 {
03334    int res = 0;
03335    res = ast_play_and_wait(chan, fn);  /* Folder name */
03336    while (((res < '0') || (res > '9')) &&
03337          (res != '#') && (res >= 0)) {
03338       res = get_folder(chan, 0);
03339    }
03340    return res;
03341 }

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

Definition at line 5834 of file app_voicemail.c.

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

05835 {
05836    struct ast_vm_user *vmu = users;
05837    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
05838 
05839    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
05840    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
05841 
05842    if (vmu) {
05843       if (argc == 3)
05844          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
05845       else {
05846          int count = 0;
05847          while (vmu) {
05848             if (!strcmp(argv[4],vmu->context))
05849                count++;
05850             vmu = vmu->next;
05851          }
05852          if (count) {
05853             vmu = users;
05854             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
05855          } else {
05856             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
05857             return RESULT_FAILURE;
05858          }
05859       }
05860       while (vmu) {
05861          int newmsgs = 0, oldmsgs = 0;
05862          char count[12], tmp[256] = "";
05863 
05864          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
05865             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
05866             messagecount(tmp, &newmsgs, &oldmsgs);
05867             snprintf(count,sizeof(count),"%d",newmsgs);
05868             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
05869          }
05870          vmu = vmu->next;
05871       }
05872    } else {
05873       ast_cli(fd, "There are no voicemail users currently defined\n");
05874       return RESULT_FAILURE;
05875    }
05876    return RESULT_SUCCESS;
05877 }

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

Definition at line 5879 of file app_voicemail.c.

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

05880 {
05881    struct vm_zone *zone = zones;
05882    char *output_format = "%-15s %-20s %-45s\n";
05883 
05884    if (argc != 3) return RESULT_SHOWUSAGE;
05885 
05886    if (zone) {
05887       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
05888       while (zone) {
05889          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
05890          zone = zone->next;
05891       }
05892    } else {
05893       ast_cli(fd, "There are no voicemail zones currently defined\n");
05894       return RESULT_FAILURE;
05895    }
05896    return RESULT_SUCCESS;
05897 }

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

Definition at line 2228 of file app_voicemail.c.

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

02229 {
02230    DIR *dir;
02231    struct dirent *de;
02232    char fn[PATH_MAX];
02233    char tmp[PATH_MAX] = "";
02234    char *mb, *cur;
02235    char *context;
02236    int ret;
02237    if (!folder)
02238       folder = "INBOX";
02239    /* If no mailbox, return immediately */
02240    if (ast_strlen_zero(mailbox))
02241       return 0;
02242    if (strchr(mailbox, ',')) {
02243       ast_copy_string(tmp, mailbox, sizeof(tmp));
02244       mb = tmp;
02245       ret = 0;
02246       while((cur = strsep(&mb, ","))) {
02247          if (!ast_strlen_zero(cur)) {
02248             if (has_voicemail(cur, folder))
02249                return 1; 
02250          }
02251       }
02252       return 0;
02253    }
02254    ast_copy_string(tmp, mailbox, sizeof(tmp));
02255    context = strchr(tmp, '@');
02256    if (context) {
02257       *context = '\0';
02258       context++;
02259    } else
02260       context = "default";
02261    snprintf(fn, sizeof(fn), "%s/%s/%s/%s", VM_SPOOL_DIR, context, tmp, folder);
02262    dir = opendir(fn);
02263    if (!dir)
02264       return 0;
02265    while ((de = readdir(dir))) {
02266       if (!strncasecmp(de->d_name, "msg", 3))
02267          break;
02268    }
02269    closedir(dir);
02270    if (de)
02271       return 1;
02272    return 0;
02273 }

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

Definition at line 1516 of file app_voicemail.c.

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

Referenced by inchar(), and vm_change_password().

01517 {
01518    int l;
01519 
01520    if (bio->ateof)
01521       return 0;
01522 
01523    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
01524       if (ferror(fi))
01525          return -1;
01526 
01527       bio->ateof = 1;
01528       return 0;
01529    }
01530 
01531    bio->iolen= l;
01532    bio->iocp= 0;
01533 
01534    return 1;
01535 }

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

Definition at line 1538 of file app_voicemail.c.

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

Referenced by base_encode().

01539 {
01540    if (bio->iocp>=bio->iolen) {
01541       if (!inbuf(bio, fi))
01542          return EOF;
01543    }
01544 
01545    return bio->iobuf[bio->iocp++];
01546 }

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

Definition at line 1965 of file app_voicemail.c.

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

Referenced by leave_voicemail().

01966 {
01967    int res;
01968    char fn[PATH_MAX];
01969    char dest[PATH_MAX];
01970 
01971    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext);
01972 
01973    if ((res = create_dirpath(dest, sizeof(dest), context, ext, "greet"))) {
01974       ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
01975       return -1;
01976    }
01977 
01978    RETRIEVE(fn, -1);
01979    if (ast_fileexists(fn, NULL, NULL) > 0) {
01980       res = ast_streamfile(chan, fn, chan->language);
01981       if (res) {
01982          DISPOSE(fn, -1);
01983          return -1;
01984       }
01985       res = ast_waitstream(chan, ecodes);
01986       if (res) {
01987          DISPOSE(fn, -1);
01988          return res;
01989       }
01990    } else {
01991       /* Dispose just in case */
01992       DISPOSE(fn, -1);
01993       res = ast_streamfile(chan, "vm-theperson", chan->language);
01994       if (res)
01995          return -1;
01996       res = ast_waitstream(chan, ecodes);
01997       if (res)
01998          return res;
01999       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
02000       if (res)
02001          return res;
02002    }
02003    if (busy)
02004       res = ast_streamfile(chan, "vm-isonphone", chan->language);
02005    else
02006       res = ast_streamfile(chan, "vm-isunavail", chan->language);
02007    if (res)
02008       return -1;
02009    res = ast_waitstream(chan, ecodes);
02010    return res;
02011 }

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

References ASTERISK_GPL_KEY.

06897 {
06898    return ASTERISK_GPL_KEY;
06899 }

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

Definition at line 1480 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().

01481 {
01482    int x;
01483    char fn[PATH_MAX];
01484 
01485    if (vm_lock_path(dir))
01486       return ERROR_LOCK_PATH;
01487 
01488    for (x = 0; x < vmu->maxmsg; x++) {
01489       make_file(fn, sizeof(fn), dir, x);
01490       if (ast_fileexists(fn, NULL, NULL) < 1)
01491          break;
01492    }
01493    ast_unlock_path(dir);
01494 
01495    return x - 1;
01496 }

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

Definition at line 2416 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().

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

static int load_config ( void   )  [static]

Definition at line 5938 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, free, free_user(), free_zone(), ast_variable::lineno, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, malloc, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, vm_zone::msg_format, vm_zone::name, ast_variable::name, ast_variable::next, vm_zone::next, ast_vm_user::next, s, SENDMAIL, strdup, strsep(), vm_zone::timezone, ast_variable::value, var, VM_ALLOCED, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_OPERATOR, VM_PBXSKIP, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, and VOICEMAIL_CONFIG.

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

int load_module ( void   ) 

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.
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.
TE STUFF END

Definition at line 6403 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(), vm_box_exists(), vm_exec(), vm_execmain(), and vmauthenticate().

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

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

Definition at line 773 of file app_voicemail.c.

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

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

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

Definition at line 778 of file app_voicemail.c.

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

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

static char* mbox ( int  id  )  [static]

Definition at line 2024 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().

02025 {
02026    switch(id) {
02027    case 0:
02028       return "INBOX";
02029    case 1:
02030       return "Old";
02031    case 2:
02032       return "Work";
02033    case 3:
02034       return "Family";
02035    case 4:
02036       return "Friends";
02037    case 5:
02038       return "Cust1";
02039    case 6:
02040       return "Cust2";
02041    case 7:
02042       return "Cust3";
02043    case 8:
02044       return "Cust4";
02045    case 9:
02046       return "Cust5";
02047    default:
02048       return "Unknown";
02049    }
02050 }

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

Definition at line 2276 of file app_voicemail.c.

References ast_strlen_zero(), and strsep().

Referenced by handle_show_voicemail_users(), load_module(), and run_externnotify().

02277 {
02278    DIR *dir;
02279    struct dirent *de;
02280    char fn[PATH_MAX];
02281    char tmp[PATH_MAX] = "";
02282    char *mb, *cur;
02283    char *context;
02284    int ret;
02285    if (newmsgs)
02286       *newmsgs = 0;
02287    if (oldmsgs)
02288       *oldmsgs = 0;
02289    /* If no mailbox, return immediately */
02290    if (ast_strlen_zero(mailbox))
02291       return 0;
02292    if (strchr(mailbox, ',')) {
02293       int tmpnew, tmpold;
02294       ast_copy_string(tmp, mailbox, sizeof(tmp));
02295       mb = tmp;
02296       ret = 0;
02297       while((cur = strsep(&mb, ", "))) {
02298          if (!ast_strlen_zero(cur)) {
02299             if (messagecount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
02300                return -1;
02301             else {
02302                if (newmsgs)
02303                   *newmsgs += tmpnew; 
02304                if (oldmsgs)
02305                   *oldmsgs += tmpold;
02306             }
02307          }
02308       }
02309       return 0;
02310    }
02311    ast_copy_string(tmp, mailbox, sizeof(tmp));
02312    context = strchr(tmp, '@');
02313    if (context) {
02314       *context = '\0';
02315       context++;
02316    } else
02317       context = "default";
02318    if (newmsgs) {
02319       snprintf(fn, sizeof(fn), "%s/%s/%s/INBOX", VM_SPOOL_DIR, context, tmp);
02320       dir = opendir(fn);
02321       if (dir) {
02322          while ((de = readdir(dir))) {
02323             if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) &&
02324                !strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt"))
02325                   (*newmsgs)++;
02326                
02327          }
02328          closedir(dir);
02329       }
02330    }
02331    if (oldmsgs) {
02332       snprintf(fn, sizeof(fn), "%s/%s/%s/Old", VM_SPOOL_DIR, context, tmp);
02333       dir = opendir(fn);
02334       if (dir) {
02335          while ((de = readdir(dir))) {
02336             if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) &&
02337                !strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt"))
02338                   (*oldmsgs)++;
02339                
02340          }
02341          closedir(dir);
02342       }
02343    }
02344    return 0;
02345 }

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 3442 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, 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().

03443 {
03444    char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
03445    int newmsgs = 0, oldmsgs = 0;
03446 
03447    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
03448    make_file(fn, sizeof(fn), todir, msgnum);
03449    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
03450 
03451    /* Attach only the first format */
03452    fmt = ast_strdupa(fmt);
03453    if (fmt) {
03454       stringp = fmt;
03455       strsep(&stringp, "|");
03456 
03457       if (!ast_strlen_zero(vmu->email)) {
03458          int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
03459          char *myserveremail = serveremail;
03460          attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
03461          if (!ast_strlen_zero(vmu->serveremail))
03462             myserveremail = vmu->serveremail;
03463          sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail);
03464       }
03465 
03466       if (!ast_strlen_zero(vmu->pager)) {
03467          char *myserveremail = serveremail;
03468          if (!ast_strlen_zero(vmu->serveremail))
03469             myserveremail = vmu->serveremail;
03470          sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu);
03471       }
03472    } else {
03473       ast_log(LOG_ERROR, "Out of memory\n");
03474    }
03475 
03476    if (ast_test_flag(vmu, VM_DELETE)) {
03477       DELETE(todir, msgnum, fn);
03478    }
03479 
03480    /* Leave voicemail for someone */
03481    if (ast_app_has_voicemail(ext_context, NULL)) {
03482       ast_app_messagecount(ext_context, &newmsgs, &oldmsgs);
03483    }
03484    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);
03485    run_externnotify(vmu->context, vmu->mailbox);
03486    return 0;
03487 }

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

Definition at line 1549 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

01550 {
01551    if (bio->linelength>=BASELINELEN) {
01552       if (fputs(eol,so)==EOF)
01553          return -1;
01554 
01555       bio->linelength= 0;
01556    }
01557 
01558    if (putc(((unsigned char)c),so)==EOF)
01559       return -1;
01560 
01561    bio->linelength++;
01562 
01563    return 1;
01564 }

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

Definition at line 3919 of file app_voicemail.c.

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

Referenced by vm_execmain().

03920 {
03921    int res = 0;
03922    int count_msg, last_msg;
03923 
03924    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
03925    
03926    /* Rename the member vmbox HERE so that we don't try to return before
03927     * we know what's going on.
03928     */
03929    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
03930    
03931    /* Faster to make the directory than to check if it exists. */
03932    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
03933 
03934    count_msg = count_messages(vmu, vms->curdir);
03935    if (count_msg < 0)
03936       return count_msg;
03937    else
03938       vms->lastmsg = count_msg - 1;
03939 
03940    /*
03941    The following test is needed in case sequencing gets messed up.
03942    There appears to be more than one way to mess up sequence, so
03943    we will not try to find all of the root causes--just fix it when
03944    detected.
03945    */
03946 
03947    last_msg = last_message_index(vmu, vms->curdir);
03948    if (last_msg < 0)
03949       return last_msg;
03950    else if(vms->lastmsg != last_msg)
03951    {
03952       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
03953       res = resequence_mailbox(vmu, vms->curdir);
03954       if (res)
03955          return res;
03956    }
03957 
03958    return 0;
03959 }

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

Definition at line 3845 of file app_voicemail.c.

References adsi_message(), ast_config_destroy(), ast_config_load(), AST_DIGIT_ANY, ast_log(), ast_say_number(), ast_strdupa, ast_test_flag, ast_variable_retrieve(), vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::fn2, vm_state::heard, 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().

03846 {
03847    int res = 0;
03848    char filename[PATH_MAX], *origtime, *cid, *context, *duration;
03849    char *category;
03850    struct ast_config *msg_cfg;
03851 
03852    vms->starting = 0; 
03853    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
03854    adsi_message(chan, vms);
03855    if (!vms->curmsg)
03856       res = wait_file2(chan, vms, "vm-first");  /* "First" */
03857    else if (vms->curmsg == vms->lastmsg)
03858       res = wait_file2(chan, vms, "vm-last");      /* "last" */
03859    if (!res) {
03860                if (!strcasecmp(chan->language, "se")) {             /* SWEDISH syntax */
03861                        res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
03862                }
03863                else {
03864                        res = wait_file2(chan, vms, "vm-message");      /* "message" */
03865                }
03866       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
03867          if (!res)
03868             res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
03869       }
03870    }
03871 
03872    /* Retrieve info from VM attribute file */
03873    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
03874    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
03875    RETRIEVE(vms->curdir, vms->curmsg);
03876    msg_cfg = ast_config_load(filename);
03877    if (!msg_cfg) {
03878       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
03879       return 0;
03880    }
03881                                                                            
03882    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
03883       ast_log(LOG_WARNING, "No origtime?!\n");
03884       DISPOSE(vms->curdir, vms->curmsg);
03885       ast_config_destroy(msg_cfg);
03886       return 0;
03887    }
03888 
03889    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
03890    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
03891    category = ast_variable_retrieve(msg_cfg, "message", "category");
03892 
03893    context = ast_variable_retrieve(msg_cfg, "message", "context");
03894    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
03895       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
03896 
03897    if (!res)
03898       res = play_message_category(chan, category);
03899    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
03900       res = play_message_datetime(chan, vmu, origtime, filename);
03901    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
03902       res = play_message_callerid(chan, vms, cid, context, 0);
03903         if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
03904                 res = play_message_duration(chan, vms, duration, vmu->saydurationm);
03905    /* Allow pressing '1' to skip envelope / callerid */
03906    if (res == '1')
03907       res = 0;
03908    ast_config_destroy(msg_cfg);
03909 
03910    if (!res) {
03911       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
03912       vms->heard[vms->curmsg] = 1;
03913       res = wait_file(chan, vms, vms->fn);
03914    }
03915    DISPOSE(vms->curdir, vms->curmsg);
03916    return res;
03917 }

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

Definition at line 3759 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().

03760 {
03761    int res = 0;
03762    int i;
03763    char *callerid, *name;
03764    char prefile[PATH_MAX] = "";
03765    
03766 
03767    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
03768    /* 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 */
03769    if ((cid == NULL)||(context == NULL))
03770       return res;
03771 
03772    /* Strip off caller ID number from name */
03773    ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
03774    ast_callerid_parse(cid, &name, &callerid);
03775    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
03776       /* Check for internal contexts and only */
03777       /* say extension when the call didn't come from an internal context in the list */
03778       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
03779          ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
03780          if ((strcmp(cidinternalcontexts[i], context) == 0))
03781             break;
03782       }
03783       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
03784          if (!res) {
03785             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
03786             if (!ast_strlen_zero(prefile)) {
03787             /* See if we can find a recorded name for this person instead of their extension number */
03788                if (ast_fileexists(prefile, NULL, NULL) > 0) {
03789                   if (option_verbose > 2)
03790                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
03791                   if (!callback)
03792                      res = wait_file2(chan, vms, "vm-from");
03793                   res = ast_streamfile(chan, prefile, chan->language) > -1;
03794                   res = ast_waitstream(chan, "");
03795                } else {
03796                   if (option_verbose > 2)
03797                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
03798                   /* BB: Say "from extension" as one saying to sound smoother */
03799                   if (!callback)
03800                      res = wait_file2(chan, vms, "vm-from-extension");
03801                   res = ast_say_digit_str(chan, callerid, "", chan->language);
03802                }
03803             }
03804          }
03805       }
03806 
03807       else if (!res){
03808          ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
03809          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
03810          if (!callback)
03811             res = wait_file2(chan, vms, "vm-from-phonenumber");
03812          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
03813       }
03814    } else {
03815       /* Number unknown */
03816       ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
03817       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
03818       res = wait_file2(chan, vms, "vm-unknown-caller");
03819    }
03820    return res;
03821 }

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

Definition at line 3676 of file app_voicemail.c.

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

Referenced by play_message().

03677 {
03678    int res = 0;
03679 
03680    if (!ast_strlen_zero(category))
03681       res = ast_play_and_wait(chan, category);
03682 
03683    if (res) {
03684       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
03685       res = 0;
03686    }
03687 
03688    return res;
03689 }

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

Definition at line 3691 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, and ast_vm_user::zonetag.

Referenced by advanced_options(), and play_message().

03692 {
03693    int res = 0;
03694    struct vm_zone *the_zone = NULL;
03695    time_t t;
03696    long tin;
03697 
03698    if (sscanf(origtime,"%30ld",&tin) < 1) {
03699       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
03700       return 0;
03701    }
03702    t = tin;
03703 
03704    /* Does this user have a timezone specified? */
03705    if (!ast_strlen_zero(vmu->zonetag)) {
03706       /* Find the zone in the list */
03707       struct vm_zone *z;
03708       z = zones;
03709       while (z) {
03710          if (!strcmp(z->name, vmu->zonetag)) {
03711             the_zone = z;
03712             break;
03713          }
03714          z = z->next;
03715       }
03716    }
03717 
03718 /* No internal variable parsing for now, so we'll comment it out for the time being */
03719 #if 0
03720    /* Set the DIFF_* variables */
03721    localtime_r(&t, &time_now);
03722    tv_now = ast_tvnow();
03723    tnow = tv_now.tv_sec;
03724    localtime_r(&tnow,&time_then);
03725 
03726    /* Day difference */
03727    if (time_now.tm_year == time_then.tm_year)
03728       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
03729    else
03730       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
03731    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
03732 
03733    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
03734 #endif
03735    if (the_zone)
03736       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
03737        else if(!strcasecmp(chan->language,"se"))       /* SWEDISH syntax */
03738                res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
03739        else if(!strcasecmp(chan->language,"no"))       /* NORWEGIAN syntax */
03740                res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
03741    else if(!strcasecmp(chan->language,"de")) /* GERMAN syntax */
03742       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
03743    else if (!strcasecmp(chan->language,"nl"))   /* DUTCH syntax */
03744       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
03745    else if (!strcasecmp(chan->language,"it"))      /* ITALIAN syntax */
03746       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);
03747    else if (!strcasecmp(chan->language,"gr"))
03748       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
03749    else
03750       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
03751 #if 0
03752    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
03753 #endif
03754    return res;
03755 }

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

Definition at line 3823 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().

03824 {
03825    int res = 0;
03826    int durationm;
03827    int durations;
03828    /* Verify that we have a duration for the message */
03829    if((duration == NULL))
03830       return res;
03831 
03832    /* Convert from seconds to minutes */
03833    durations=atoi(duration);
03834    durationm=(durations / 60);
03835 
03836    ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
03837 
03838    if((!res)&&(durationm>=minduration)) {
03839       res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, (char *) NULL);
03840       res = wait_file2(chan, vms, "vm-minutes");
03841    }
03842    return res;
03843 }

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

References ast_channel_setoption(), AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_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_exec(), VM_OPERATOR, and VM_REVIEW.

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

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

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

Definition at line 425 of file app_voicemail.c.

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

Referenced by append_mailbox(), and find_user_realtime().

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

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

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

Referenced by sendmail(), and sendpage().

01639 {
01640    char callerid[256];
01641    /* Prepare variables for substition in email body and subject */
01642    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
01643    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
01644    snprintf(passdata, passdatasize, "%d", msgnum);
01645    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
01646    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
01647    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
01648    pbx_builtin_setvar_helper(ast, "VM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller"));
01649    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (cidname ? cidname : "an unknown caller"));
01650    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
01651    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
01652 }

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

Definition at line 1654 of file app_voicemail.c.

Referenced by sendmail().

01655 {
01656    char *ptr = to;
01657    *ptr++ = '"';
01658    for (; ptr < to + len - 1; from++) {
01659       if (*from == '"')
01660          *ptr++ = '\\';
01661       else if (*from == '\0')
01662          break;
01663       *ptr++ = *from;
01664    }
01665    if (ptr < to + len - 1)
01666       *ptr++ = '"';
01667    *ptr = '\0';
01668    return to;
01669 }

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

References load_config().

06382 {
06383    return(load_config());
06384 }

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

Definition at line 1408 of file app_voicemail.c.

References ast_filerename().

01409 {
01410    char stxt[PATH_MAX];
01411    char dtxt[PATH_MAX];
01412    ast_filerename(sfn,dfn,NULL);
01413    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
01414    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
01415    rename(stxt, dtxt);
01416 }

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

Definition at line 2745 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().

02746 {
02747    /* we know max messages, so stop process when number is hit */
02748 
02749    int x,dest;
02750    char sfn[PATH_MAX];
02751    char dfn[PATH_MAX];
02752 
02753    if (vm_lock_path(dir))
02754       return ERROR_LOCK_PATH;
02755 
02756    for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
02757       make_file(sfn, sizeof(sfn), dir, x);
02758       if (EXISTS(dir, x, sfn, NULL)) {
02759          
02760          if(x != dest) {
02761             make_file(dfn, sizeof(dfn), dir, dest);
02762             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
02763          }
02764          
02765          dest++;
02766       }
02767    }
02768    ast_unlock_path(dir);
02769 
02770    return 0;
02771 }

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

Definition at line 610 of file app_voicemail.c.

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

Referenced by vm_change_password(), and vm_change_password_shell().

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

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

Definition at line 2389 of file app_voicemail.c.

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

Referenced by notify_new_message(), and vm_execmain().

02390 {
02391    char arguments[255];
02392    char ext_context[256] = "";
02393    int newvoicemails = 0, oldvoicemails = 0;
02394 
02395    if (!ast_strlen_zero(context))
02396       snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
02397    else
02398       ast_copy_string(ext_context, extension, sizeof(ext_context));
02399 
02400    if (!ast_strlen_zero(externnotify)) {
02401       if (messagecount(ext_context, &newvoicemails, &oldvoicemails)) {
02402          ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
02403       } else {
02404          snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
02405          ast_log(LOG_DEBUG, "Executing %s\n", arguments);
02406          ast_safe_system(arguments);
02407       }
02408    }
02409 }

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

Definition at line 2781 of file app_voicemail.c.

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

Referenced by close_mailbox(), and vm_execmain().

02782 {
02783    char sfn[PATH_MAX];
02784    char dfn[PATH_MAX];
02785    char ddir[PATH_MAX];
02786    char *dbox = mbox(box);
02787    int x;
02788    make_file(sfn, sizeof(sfn), dir, msg);
02789    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
02790 
02791    if (vm_lock_path(ddir))
02792       return ERROR_LOCK_PATH;
02793 
02794    for (x = 0; x < vmu->maxmsg; x++) {
02795       make_file(dfn, sizeof(dfn), ddir, x);
02796       if (!EXISTS(ddir, x, dfn, NULL))
02797          break;
02798    }
02799    if (x >= vmu->maxmsg) {
02800       ast_unlock_path(ddir);
02801       return -1;
02802    }
02803    if (strcmp(sfn, dfn)) {
02804       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
02805    }
02806    ast_unlock_path(ddir);
02807    
02808    return 0;
02809 }

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

Definition at line 2774 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().

02775 {
02776    int d;
02777    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
02778    return d;
02779 }

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 1671 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, host, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, vm_zone::name, vm_zone::next, pbx_substitute_variables_helper(), prep_email_sub_vars(), quote(), t, vm_zone::timezone, VM_ATTACH, VM_PBXSKIP, and ast_vm_user::zonetag.

Referenced by notify_new_message().

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

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 1840 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, and ast_vm_user::zonetag.

Referenced by notify_new_message().

01841 {
01842    FILE *p=NULL;
01843    int pfd;
01844    char date[256];
01845    char host[MAXHOSTNAMELEN] = "";
01846    char who[256];
01847    char dur[PATH_MAX];
01848    char tmp[80] = "/tmp/astmail-XXXXXX";
01849    char tmp2[PATH_MAX];
01850    time_t t;
01851    struct tm tm;
01852    struct vm_zone *the_zone = NULL;
01853    pfd = mkstemp(tmp);
01854 
01855    if (pfd > -1) {
01856       p = fdopen(pfd, "w");
01857       if (!p) {
01858          close(pfd);
01859          pfd = -1;
01860       }
01861    }
01862 
01863    if (p) {
01864       gethostname(host, sizeof(host)-1);
01865       if (strchr(srcemail, '@'))
01866          ast_copy_string(who, srcemail, sizeof(who));
01867       else {
01868          snprintf(who, sizeof(who), "%s@%s", srcemail, host);
01869       }
01870       snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
01871       time(&t);
01872 
01873       /* Does this user have a timezone specified? */
01874       if (!ast_strlen_zero(vmu->zonetag)) {
01875          /* Find the zone in the list */
01876          struct vm_zone *z;
01877          z = zones;
01878          while (z) {
01879             if (!strcmp(z->name, vmu->zonetag)) {
01880                the_zone = z;
01881                break;
01882             }
01883             z = z->next;
01884          }
01885       }
01886 
01887       if (the_zone)
01888          ast_localtime(&t,&tm,the_zone->timezone);
01889       else
01890          ast_localtime(&t,&tm,NULL);
01891 
01892       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm);
01893       fprintf(p, "Date: %s\n", date);
01894 
01895       if (*pagerfromstring) {
01896          struct ast_channel *ast = ast_channel_alloc(0);
01897          if (ast) {
01898             char *passdata;
01899             int vmlen = strlen(fromstring)*3 + 200;
01900             if ((passdata = alloca(vmlen))) {
01901                memset(passdata, 0, vmlen);
01902                prep_email_sub_vars(ast,vmu,msgnum + 1,context,mailbox,cidnum, cidname,dur,date,passdata, vmlen);
01903                pbx_substitute_variables_helper(ast,pagerfromstring,passdata,vmlen);
01904                fprintf(p, "From: %s <%s>\n",passdata,who);
01905             } else 
01906                ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01907             ast_channel_free(ast);
01908          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01909       } else
01910          fprintf(p, "From: Asterisk PBX <%s>\n", who);
01911       fprintf(p, "To: %s\n", pager);
01912                if (pagersubject) {
01913                        struct ast_channel *ast = ast_channel_alloc(0);
01914                        if (ast) {
01915                                char *passdata;
01916                                int vmlen = strlen(pagersubject)*3 + 200;
01917                                if ((passdata = alloca(vmlen))) {
01918                                        memset(passdata, 0, vmlen);
01919                                        prep_email_sub_vars(ast,vmu,msgnum + 1,context,mailbox,cidnum, cidname,dur,date,passdata, vmlen);
01920                                        pbx_substitute_variables_helper(ast,pagersubject,passdata,vmlen);
01921                                        fprintf(p, "Subject: %s\n\n",passdata);
01922                                } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01923                                ast_channel_free(ast);
01924                        } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01925                } else
01926                        fprintf(p, "Subject: New VM\n\n");
01927       strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
01928                if (pagerbody) {
01929                        struct ast_channel *ast = ast_channel_alloc(0);
01930                        if (ast) {
01931                                char *passdata;
01932                                int vmlen = strlen(pagerbody)*3 + 200;
01933                                if ((passdata = alloca(vmlen))) {
01934                                        memset(passdata, 0, vmlen);
01935                                        prep_email_sub_vars(ast,vmu,msgnum + 1,context,mailbox,cidnum, cidname,dur,date,passdata, vmlen);
01936                                        pbx_substitute_variables_helper(ast,pagerbody,passdata,vmlen);
01937                                        fprintf(p, "%s\n",passdata);
01938                                } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01939                                ast_channel_free(ast);
01940                        } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01941                } else {
01942                        fprintf(p, "New %s long msg in box %s\n"
01943                                        "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
01944                }
01945       fclose(p);
01946       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
01947       ast_safe_system(tmp2);
01948       ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd);
01949    } else {
01950       ast_log(LOG_WARNING, "Unable to launch '%s'\n", mailcmd);
01951       return -1;
01952    }
01953    return 0;
01954 }

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

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

06387 {
06388    int res;
06389    
06390    res = ast_unregister_application(app);
06391    res |= ast_unregister_application(app2);
06392    res |= ast_unregister_application(app3);
06393    res |= ast_unregister_application(app4);
06394    res |= ast_cli_unregister(&show_voicemail_users_cli);
06395    res |= ast_cli_unregister(&show_voicemail_zones_cli);
06396    ast_uninstall_vm_functions();
06397    
06398    STANDARD_HANGUP_LOCALUSERS;
06399 
06400    return res;
06401 }

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

References STANDARD_USECOUNT.

06890 {
06891    int res;
06892    STANDARD_USECOUNT(res);
06893    return res;
06894 }

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

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

Referenced by vm_execmain(), and vmauthenticate().

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

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

Definition at line 5734 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, ast_channel::exten, find_user(), LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, LOG_WARNING, mbox(), option_priority_jumping, pbx_builtin_setvar_helper(), and ast_channel::priority.

Referenced by load_module().

05735 {
05736    struct localuser *u;
05737    struct ast_vm_user svm;
05738    char *context, *box;
05739    int priority_jump = 0;
05740    AST_DECLARE_APP_ARGS(args,
05741       AST_APP_ARG(mbox);
05742       AST_APP_ARG(options);
05743    );
05744 
05745    if (ast_strlen_zero(data)) {
05746       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
05747       return -1;
05748    }
05749 
05750    LOCAL_USER_ADD(u);
05751 
05752    box = ast_strdupa(data);
05753    if (!box) {
05754       ast_log(LOG_ERROR, "Out of memory\n");
05755       LOCAL_USER_REMOVE(u);
05756       return -1;
05757    }
05758 
05759    AST_STANDARD_APP_ARGS(args, box);
05760 
05761    if (args.options) {
05762       if (strchr(args.options, 'j'))
05763          priority_jump = 1;
05764    }
05765 
05766    if ((context = strchr(args.mbox, '@'))) {
05767       *context = '\0';
05768       context++;
05769    }
05770 
05771    if (find_user(&svm, context, args.mbox)) {
05772       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
05773       if (priority_jump || option_priority_jumping)
05774          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
05775             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);
05776    } else
05777       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
05778    LOCAL_USER_REMOVE(u);
05779    return 0;
05780 }

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

Definition at line 5027 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().

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

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

Definition at line 4950 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().

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

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

Definition at line 4990 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().

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

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

Definition at line 4922 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().

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

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

Definition at line 4971 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().

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

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

Definition at line 5009 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().

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

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

Definition at line 631 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().

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

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

Definition at line 763 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().

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

static int vm_delete ( char *  file  )  [static]

Definition at line 1498 of file app_voicemail.c.

References ast_filedelete().

01499 {
01500    char *txt;
01501    int txtsize = 0;
01502 
01503    txtsize = (strlen(file) + 5)*sizeof(char);
01504    txt = (char *)alloca(txtsize);
01505    /* Sprintf here would safe because we alloca'd exactly the right length,
01506     * but trying to eliminate all sprintf's anyhow
01507     */
01508    snprintf(txt, txtsize, "%s.txt", file);
01509    unlink(txt);
01510    return ast_filedelete(file, NULL);
01511 }

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

Definition at line 5601 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, ast_channel::context, ERROR_LOCK_PATH, ast_channel::exten, 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, pbx_builtin_setvar_helper(), ast_channel::priority, and leave_vm_options::record_gain.

Referenced by load_module(), and play_record_review().

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

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

Definition at line 5143 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(), vm_state::curdir, vm_state::curmsg, vm_state::deleted, dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), vm_state::fn, forward_message(), free, free_user(), get_folder2(), has_voicemail(), vm_state::heard, ast_channel::language, ast_vm_user::language, vm_state::lastmsg, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_NOTICE, LOG_WARNING, ast_vm_user::mailbox, make_file(), manager_event(), ast_vm_user::maxmsg, mbox(), vm_state::newmessages, vm_state::oldmessages, open_mailbox(), OPT_ARG_ARRAY_SIZE, OPT_ARG_RECORDGAIN, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, option_verbose, ast_vm_user::password, play_message(), vm_state::repeats, run_externnotify(), save_to_folder(), say_and_wait(), vm_state::starting, vm_state::username, VERBOSE_PREFIX_3, vm_authenticate(), vm_browse_messages(), VM_FORCEGREET, VM_FORCENAME, vm_instructions(), vm_intro(), vm_newuser(), vm_options(), vm_play_folder_name(), VM_SKIPAFTERCMD, VM_SVMAIL, and vm_state::vmbox.

Referenced by load_module().

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

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

Definition at line 3343 of file app_voicemail.c.

References ast_category_detach_variables(), ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_waitfordigit(), config_text_file_save(), free, ast_vm_user::mailbox, make_file(), ast_variable::next, STORE, and var.

Referenced by forward_message().

03345 {
03346    int cmd = 0;
03347    int retries = 0;
03348    signed char zero_gain = 0;
03349 
03350    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
03351       if (cmd)
03352          retries = 0;
03353       switch (cmd) {
03354       case '1': 
03355          /* prepend a message to the current message, update the metadata and return */
03356       {
03357          char msgfile[PATH_MAX];
03358          char textfile[PATH_MAX];
03359          int prepend_duration = 0;
03360          struct ast_config *msg_cfg;
03361          char *duration_str;
03362 
03363          make_file(msgfile, sizeof(msgfile), curdir, curmsg);
03364          strcpy(textfile, msgfile);
03365          strncat(textfile, ".txt", sizeof(textfile) - 1);
03366          *duration = 0;
03367 
03368          /* if we can't read the message metadata, stop now */
03369          if (!(msg_cfg = ast_config_load(textfile))) {
03370             cmd = 0;
03371             break;
03372          }
03373 
03374          if (record_gain)
03375             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
03376 
03377          cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
03378          if (record_gain)
03379             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
03380 
03381          
03382          if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
03383             *duration = atoi(duration_str);
03384 
03385          if (prepend_duration) {
03386             struct ast_variable *var, *prev = NULL, *varlist;
03387             struct ast_category *msg_cat;
03388 
03389             *duration += prepend_duration;
03390             msg_cat = ast_category_get(msg_cfg, "message");
03391             varlist = ast_category_detach_variables(msg_cat);
03392             for (var = varlist; var; prev = var, var = var->next) {
03393                if (!strcmp(var->name, "duration")) {
03394                   if (!prev)
03395                      varlist = var->next;
03396                   else
03397                      prev->next = var->next;
03398                   free(var);
03399                   break;
03400                }
03401             }
03402             /* need enough space for a maximum-length message duration */
03403             duration_str = alloca(12);
03404             snprintf(duration_str, 11, "%ld", *duration);
03405             if ((var = ast_variable_new("duration", duration_str))) {
03406                ast_variable_append(msg_cat, varlist);
03407                ast_variable_append(msg_cat, var);
03408                config_text_file_save(textfile, msg_cfg, "app_voicemail");
03409                STORE(curdir, vmu->mailbox, context, curmsg);
03410             }
03411          }
03412 
03413          ast_config_destroy(msg_cfg);
03414 
03415          break;
03416       }
03417       case '2': 
03418          cmd = 't';
03419          break;
03420       case '*':
03421          cmd = '*';
03422          break;
03423       default: 
03424          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
03425             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
03426          if (!cmd)
03427             cmd = ast_play_and_wait(chan,"vm-starmain");
03428             /* "press star to return to the main menu" */
03429          if (!cmd)
03430             cmd = ast_waitfordigit(chan,6000);
03431          if (!cmd)
03432             retries++;
03433          if (retries > 3)
03434             cmd = 't';
03435        }
03436    }
03437    if (cmd == 't' || cmd == 'S')
03438       cmd = 0;
03439    return cmd;
03440 }

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

Definition at line 4625 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().

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

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

Definition at line 4597 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(), and vm_intro_se().

Referenced by vm_execmain().

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

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

Definition at line 4537 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().

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

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

Definition at line 4278 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().

04279 {
04280    /* Introduce messages they have */
04281    int res;
04282    res = ast_play_and_wait(chan, "vm-youhave");
04283    if (!res) {
04284       if (vms->newmessages) {
04285          if ((vms->newmessages == 1))
04286             res = ast_play_and_wait(chan, "digits/1F");
04287          else
04288             res = say_and_wait(chan, vms->newmessages, chan->language);
04289          if (!res)
04290             res = ast_play_and_wait(chan, "vm-INBOX");
04291          if (vms->oldmessages && !res)
04292             res = ast_play_and_wait(chan, "vm-and");
04293          else if (!res) {
04294             if ((vms->newmessages == 1))
04295                res = ast_play_and_wait(chan, "vm-message");
04296             else
04297                res = ast_play_and_wait(chan, "vm-messages");
04298          }
04299             
04300       }
04301       if (!res && vms->oldmessages) {
04302          if (vms->oldmessages == 1)
04303             res = ast_play_and_wait(chan, "digits/1F");
04304          else
04305             res = say_and_wait(chan, vms->oldmessages, chan->language);
04306          if (!res)
04307             res = ast_play_and_wait(chan, "vm-Old");
04308          if (!res) {
04309             if (vms->oldmessages == 1)
04310                res = ast_play_and_wait(chan, "vm-message");
04311             else
04312                res = ast_play_and_wait(chan, "vm-messages");
04313          }
04314       }
04315       if (!res) {
04316          if (!vms->oldmessages && !vms->newmessages) {
04317             res = ast_play_and_wait(chan, "vm-no");
04318             if (!res)
04319                res = ast_play_and_wait(chan, "vm-messages");
04320          }
04321       }
04322    }
04323    return res;
04324 }

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

Definition at line 4112 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().

04113 {
04114    /* Introduce messages they have */
04115    int res;
04116    res = ast_play_and_wait(chan, "vm-youhave");
04117    if (!res) {
04118       if (vms->newmessages) {
04119          res = say_and_wait(chan, vms->newmessages, chan->language);
04120          if (!res)
04121             res = ast_play_and_wait(chan, "vm-INBOX");
04122          if (vms->oldmessages && !res)
04123             res = ast_play_and_wait(chan, "vm-and");
04124          else if (!res) {
04125             if ((vms->newmessages == 1))
04126                res = ast_play_and_wait(chan, "vm-message");
04127             else
04128                res = ast_play_and_wait(chan, "vm-messages");
04129          }
04130             
04131       }
04132       if (!res && vms->oldmessages) {
04133          res = say_and_wait(chan, vms->oldmessages, chan->language);
04134          if (!res)
04135             res = ast_play_and_wait(chan, "vm-Old");
04136          if (!res) {
04137             if (vms->oldmessages == 1)
04138                res = ast_play_and_wait(chan, "vm-message");
04139             else
04140                res = ast_play_and_wait(chan, "vm-messages");
04141          }
04142       }
04143       if (!res) {
04144          if (!vms->oldmessages && !vms->newmessages) {
04145             res = ast_play_and_wait(chan, "vm-no");
04146             if (!res)
04147                res = ast_play_and_wait(chan, "vm-messages");
04148          }
04149       }
04150    }
04151    return res;
04152 }

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

Definition at line 4327 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().

04328 {
04329    /* Introduce messages they have */
04330    int res;
04331    if (!vms->oldmessages && !vms->newmessages) {
04332       res = ast_play_and_wait(chan, "vm-youhaveno");
04333       if (!res)
04334          res = ast_play_and_wait(chan, "vm-messages");
04335    } else {
04336       res = ast_play_and_wait(chan, "vm-youhave");
04337    }
04338    if (!res) {
04339       if (vms->newmessages) {
04340          if (!res) {
04341             if ((vms->newmessages == 1)) {
04342                res = ast_play_and_wait(chan, "digits/1M");
04343                if (!res)
04344                   res = ast_play_and_wait(chan, "vm-message");
04345                if (!res)
04346                   res = ast_play_and_wait(chan, "vm-INBOXs");
04347             } else {
04348                res = say_and_wait(chan, vms->newmessages, chan->language);
04349                if (!res)
04350                   res = ast_play_and_wait(chan, "vm-messages");
04351                if (!res)
04352                   res = ast_play_and_wait(chan, "vm-INBOX");
04353             }
04354          }
04355          if (vms->oldmessages && !res)
04356             res = ast_play_and_wait(chan, "vm-and");
04357       }
04358       if (vms->oldmessages) {
04359          if (!res) {
04360             if (vms->oldmessages == 1) {
04361                res = ast_play_and_wait(chan, "digits/1M");
04362                if (!res)
04363                   res = ast_play_and_wait(chan, "vm-message");
04364                if (!res)
04365                   res = ast_play_and_wait(chan, "vm-Olds");
04366             } else {
04367                res = say_and_wait(chan, vms->oldmessages, chan->language);
04368                if (!res)
04369                   res = ast_play_and_wait(chan, "vm-messages");
04370                if (!res)
04371                   res = ast_play_and_wait(chan, "vm-Old");
04372             }
04373          }
04374       }
04375    }
04376 return res;
04377 }

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

Definition at line 4380 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().

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

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

Definition at line 4074 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().

04075 {
04076    int res = 0;
04077 
04078    if (vms->newmessages) {
04079       res = ast_play_and_wait(chan, "vm-youhave");
04080       if (!res) 
04081          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
04082       if (!res) {
04083          if ((vms->newmessages == 1)) {
04084             res = ast_play_and_wait(chan, "vm-INBOX");
04085             if (!res)
04086                res = ast_play_and_wait(chan, "vm-message");
04087          } else {
04088             res = ast_play_and_wait(chan, "vm-INBOXs");
04089             if (!res)
04090                res = ast_play_and_wait(chan, "vm-messages");
04091          }
04092       }    
04093    } else if (vms->oldmessages){
04094       res = ast_play_and_wait(chan, "vm-youhave");
04095       if (!res)
04096          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
04097       if ((vms->oldmessages == 1)){
04098          res = ast_play_and_wait(chan, "vm-Old");
04099          if (!res)
04100             res = ast_play_and_wait(chan, "vm-message");
04101       } else {
04102          res = ast_play_and_wait(chan, "vm-Olds");
04103          if (!res)
04104             res = ast_play_and_wait(chan, "vm-messages");
04105       }
04106     } else if (!vms->oldmessages && !vms->newmessages) 
04107          res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
04108     return res;
04109 }

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

Definition at line 4155 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().

04156 {
04157    /* Introduce messages they have */
04158    int res;
04159    if (!vms->oldmessages && !vms->newmessages)
04160       res = ast_play_and_wait(chan, "vm-no") ||
04161          ast_play_and_wait(chan, "vm-message");
04162    else
04163       res = ast_play_and_wait(chan, "vm-youhave");
04164    if (!res && vms->newmessages) {
04165       res = (vms->newmessages == 1) ?
04166          ast_play_and_wait(chan, "digits/un") ||
04167          ast_play_and_wait(chan, "vm-nuovo") ||
04168          ast_play_and_wait(chan, "vm-message") :
04169          /* 2 or more new messages */
04170          say_and_wait(chan, vms->newmessages, chan->language) ||
04171          ast_play_and_wait(chan, "vm-nuovi") ||
04172          ast_play_and_wait(chan, "vm-messages");
04173       if (!res && vms->oldmessages)
04174          res = ast_play_and_wait(chan, "vm-and");
04175    }
04176    if (!res && vms->oldmessages) {
04177       res = (vms->oldmessages == 1) ?
04178          ast_play_and_wait(chan, "digits/un") ||
04179          ast_play_and_wait(chan, "vm-vecchio") ||
04180          ast_play_and_wait(chan, "vm-message") :
04181          /* 2 or more old messages */
04182          say_and_wait(chan, vms->oldmessages, chan->language) ||
04183          ast_play_and_wait(chan, "vm-vecchi") ||
04184          ast_play_and_wait(chan, "vm-messages");
04185    }
04186    return res;
04187 }

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

Definition at line 4423 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().

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

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

Definition at line 4234 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().

04235 {
04236         /* Introduce messages they have */
04237         int res;
04238 
04239    res = ast_play_and_wait(chan, "vm-youhave");
04240    if (res)
04241       return res;
04242 
04243         if (!vms->oldmessages && !vms->newmessages) {
04244       res = ast_play_and_wait(chan, "vm-no");
04245       res = res ? res : ast_play_and_wait(chan, "vm-messages");
04246       return res;
04247         }
04248 
04249    if (vms->newmessages) {
04250       if ((vms->newmessages == 1)) {
04251          res = ast_play_and_wait(chan, "digits/1");
04252          res = res ? res : ast_play_and_wait(chan, "vm-ny");
04253          res = res ? res : ast_play_and_wait(chan, "vm-message");
04254       } else {
04255          res = say_and_wait(chan, vms->newmessages, chan->language);
04256          res = res ? res : ast_play_and_wait(chan, "vm-nye");
04257          res = res ? res : ast_play_and_wait(chan, "vm-messages");
04258       }
04259       if (!res && vms->oldmessages)
04260          res = ast_play_and_wait(chan, "vm-and");
04261    }
04262    if (!res && vms->oldmessages) {
04263       if (vms->oldmessages == 1) {
04264          res = ast_play_and_wait(chan, "digits/1");
04265          res = res ? res : ast_play_and_wait(chan, "vm-gamel");
04266          res = res ? res : ast_play_and_wait(chan, "vm-message");
04267       } else {
04268          res = say_and_wait(chan, vms->oldmessages, chan->language);
04269          res = res ? res : ast_play_and_wait(chan, "vm-gamle");
04270          res = res ? res : ast_play_and_wait(chan, "vm-messages");
04271       }
04272    }
04273 
04274    return res;
04275 }

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

Definition at line 4474 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().

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

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

Definition at line 4190 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().

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

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

Definition at line 821 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().

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

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 4672 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_log(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_flag, ast_vm_user::context, LOG_NOTICE, play_record_review(), vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, and VM_FORCENAME.

Referenced by vm_execmain().

04673 {
04674    int cmd = 0;
04675    int duration = 0;
04676    int tries = 0;
04677    char newpassword[80] = "";
04678    char newpassword2[80] = "";
04679    char prefile[PATH_MAX] =