Thu Mar 25 10:39:20 2010

Asterisk developer's documentation


app_voicemail.c File Reference

Comedian Mail - Voicemail System. More...

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

Go to the source code of this file.

Data Structures

struct  ast_vm_user
struct  baseio
struct  leave_vm_options
struct  users
struct  vm_state
struct  vm_zone
struct  zones

Defines

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

Enumerations

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

Functions

static int __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit)
static void __reg_module (void)
static void __unreg_module (void)
static void adsi_begin (struct ast_channel *chan, int *useadsi)
static void adsi_delete (struct ast_channel *chan, struct vm_state *vms)
static void adsi_folders (struct ast_channel *chan, int start, char *label)
static void adsi_goodbye (struct ast_channel *chan)
static int adsi_load_vmail (struct ast_channel *chan, int *useadsi)
static void adsi_login (struct ast_channel *chan)
static int adsi_logo (unsigned char *buf)
static void adsi_message (struct ast_channel *chan, struct vm_state *vms)
static void adsi_password (struct ast_channel *chan)
static void adsi_status (struct ast_channel *chan, struct vm_state *vms)
static void adsi_status2 (struct ast_channel *chan, struct vm_state *vms)
static int advanced_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain)
static int append_mailbox (char *context, char *mbox, char *data)
static void apply_option (struct ast_vm_user *vmu, const char *var, const char *value)
static void apply_options (struct ast_vm_user *vmu, const char *options)
static void apply_options_full (struct ast_vm_user *retval, struct ast_variable *var)
static int base_encode (char *filename, FILE *so)
static int change_password_realtime (struct ast_vm_user *vmu, const char *password)
static int check_mime (const char *str)
 Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean.
static int close_mailbox (struct vm_state *vms, struct ast_vm_user *vmu)
static char * complete_voicemail_show_users (const char *line, const char *word, int pos, int state)
static int copy (char *infile, char *outfile)
static int copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir)
static void copy_plain_file (char *frompath, char *topath)
static int count_messages (struct ast_vm_user *vmu, char *dir)
static int create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder)
 basically mkdir -p $dest/$context/$ext/$folder
static int dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
static char * encode_mime_str (const char *start, char *end, size_t endsize, size_t preamble, size_t postamble)
 Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters.
static struct ast_vm_userfind_or_create (char *context, char *mbox)
static struct ast_vm_userfind_user (struct ast_vm_user *ivm, const char *context, const char *mailbox)
static struct ast_vm_userfind_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox)
static int forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int flag, signed char record_gain)
static void free_user (struct ast_vm_user *vmu)
static void free_vm_users (void)
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_voicemail_show_users (int fd, int argc, char *argv[])
static int handle_voicemail_show_zones (int fd, int argc, char *argv[])
static int has_voicemail (const char *mailbox, const char *folder)
static int inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs)
static int inbuf (struct baseio *bio, FILE *fi)
static int inchar (struct baseio *bio, FILE *fi)
static int invent_message (struct ast_channel *chan, struct ast_vm_user *vmu, char *ext, int busy, char *ecodes)
static int last_message_index (struct ast_vm_user *vmu, char *dir)
static int leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options)
static int load_config (void)
static int load_module (void)
static int make_dir (char *dest, int len, const char *context, const char *ext, const char *folder)
static void make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *folder, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap)
static int make_file (char *dest, const int len, const char *dir, const int num)
static char * mbox (int id)
static int messagecount (const char *context, const char *mailbox, const char *folder)
static int notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
static int ochar (struct baseio *bio, int c, FILE *so)
static int open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box)
static int play_greeting (struct ast_channel *chan, struct ast_vm_user *vmu, char *filename, char *ecodes)
static int play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback)
static int play_message_category (struct ast_channel *chan, const char *category)
static int play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename)
static int play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration)
static int play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir, signed char record_gain, struct vm_state *vms)
static void populate_defaults (struct ast_vm_user *vmu)
static void prep_email_sub_vars (struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, char *passdata, size_t passdatasize, const char *category)
static char * quote (const char *from, char *to, size_t len)
static int reload (void)
static void rename_file (char *sfn, char *dfn)
static int resequence_mailbox (struct ast_vm_user *vmu, char *dir)
static int reset_user_pw (const char *context, const char *mailbox, const char *newpass)
static void run_externnotify (char *context, char *extension)
static int save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box)
static int say_and_wait (struct ast_channel *chan, int num, const char *language)
static int sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *fromfolder, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category)
static int sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category)
static char * strip_control_and_high (const char *input, char *buf, size_t buflen)
 Strips control and non 7-bit clean characters from input string.
static int unload_module (void)
static int vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int maxlogins, int silent)
static int vm_box_exists (struct ast_channel *chan, void *data)
static int vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_latin (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static void vm_change_password (struct ast_vm_user *vmu, const char *newpassword)
static void vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword)
static int vm_delete (char *file)
static int vm_exec (struct ast_channel *chan, void *data)
static int vm_execmain (struct ast_channel *chan, void *data)
static int vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vmfmts, char *context, signed char record_gain, long *duration, struct vm_state *vms)
static int vm_instructions (struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
static int vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int vm_intro_cs (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_he (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_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[])
static int vm_intro_nl (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_no (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pl (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pt (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_se (struct ast_channel *chan, struct vm_state *vms)
static int vm_lock_path (const char *path)
static FILE * vm_mkftemp (char *template)
static int vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int vm_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int vm_play_folder_name (struct ast_channel *chan, char *mbox)
static int vm_play_folder_name_gr (struct ast_channel *chan, char *mbox)
static int vm_play_folder_name_pl (struct ast_channel *chan, char *mbox)
static int vm_play_folder_name_ua (struct ast_channel *chan, char *mbox)
static int vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int vmauthenticate (struct ast_channel *chan, void *data)
static struct tm * vmu_tm (const struct ast_vm_user *vmu, struct tm *tm)
static int wait_file (struct ast_channel *chan, struct vm_state *vms, char *file)
static int wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, }
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 const struct ast_module_infoast_module_info = &__mod_info
static char callcontext [AST_MAX_CONTEXT]
static char charset [32] = "ISO-8859-1"
static char cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64]
static struct ast_cli_entry cli_show_voicemail_users_deprecated
static struct ast_cli_entry cli_show_voicemail_zones_deprecated
static struct ast_cli_entry cli_voicemail []
static char * descrip_vm
static char * descrip_vm_box_exists
static char * descrip_vmain
static char * descrip_vmauthenticate
static char dialcontext [AST_MAX_CONTEXT]
static char * emailbody = NULL
static char emaildateformat [32] = "%A, %B %d, %Y at %r"
static char * emailsubject = NULL
static char emailtitle [100]
static char exitcontext [AST_MAX_CONTEXT]
static char ext_pass_cmd [128]
static char externnotify [160]
static char fromstring [100]
static struct ast_flags globalflags = {0}
static char mailcmd [160]
static int maxgreet
static int maxlogins
static int maxmsg
static int maxsilence
static int my_umask
static char * pagerbody = NULL
static char pagerfromstring [100]
static char * pagersubject = NULL
static char preprocesscmd [160]
static char preprocessfmt [20]
static int saydurationminfo
static char serveremail [80]
static int silencethreshold = 128
static int skipms
static struct ast_smdi_interfacesmdi_iface = NULL
static char * synopsis_vm
static char * synopsis_vm_box_exists
static char * synopsis_vmain
static char * synopsis_vmauthenticate
static char userscontext [AST_MAX_EXTENSION] = "default"
static struct ast_app_option vm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'j' ] = { .flag = OPT_PRIORITY_JUMP }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 },}
enum { ... }  vm_option_args
enum { ... }  vm_option_flags
static char VM_SPOOL_DIR [PATH_MAX]
static char vmfmts [80]
static int vmmaxmessage
static int vmminmessage
static char voicemail_show_users_help []
static char voicemail_show_zones_help []
static double volgain
static char zonetag [80]


Detailed Description

Comedian Mail - Voicemail System.

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

Definition in file app_voicemail.c.


Define Documentation

#define ASTERISK_USERNAME   "asterisk"

Definition at line 169 of file app_voicemail.c.

Referenced by load_config().

#define BASELINELEN   72

Definition at line 185 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 186 of file app_voicemail.c.

#define BASEMAXINLINE   256

Definition at line 186 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 166 of file app_voicemail.c.

#define COMMAND_TIMEOUT   5000

Definition at line 162 of file app_voicemail.c.

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

Definition at line 438 of file app_voicemail.c.

Referenced by copy_message().

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

Definition at line 439 of file app_voicemail.c.

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

#define DISPOSE ( a,
 ) 

Definition at line 434 of file app_voicemail.c.

Referenced by advanced_options(), forward_message(), leave_voicemail(), notify_new_message(), play_greeting(), play_message(), play_record_review(), vm_intro(), vm_options(), and vm_tempgreeting().

#define ENDL   "\n"

Referenced by make_email_file().

#define eol   "\r\n"

Definition at line 187 of file app_voicemail.c.

Referenced by base_encode(), and ochar().

#define ERROR_LOCK_PATH   -100

Definition at line 208 of file app_voicemail.c.

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

#define ERROR_MAILBOX_FULL   -200

Definition at line 209 of file app_voicemail.c.

Referenced by save_to_folder().

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

Definition at line 436 of file app_voicemail.c.

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

#define INTRO   "vm-intro"

Definition at line 175 of file app_voicemail.c.

Referenced by leave_voicemail(), and play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 189 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 190 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 177 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

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

Referenced by close_mailbox(), and resequence_mailbox().

#define RETRIEVE ( a,
b,
 ) 

Definition at line 433 of file app_voicemail.c.

Referenced by advanced_options(), forward_message(), leave_voicemail(), notify_new_message(), play_greeting(), play_message(), vm_intro(), vm_options(), and vm_tempgreeting().

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

Definition at line 173 of file app_voicemail.c.

Referenced by load_config().

#define SMDI_MWI_WAIT_TIMEOUT   1000

Definition at line 160 of file app_voicemail.c.

Referenced by run_externnotify().

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

Definition at line 435 of file app_voicemail.c.

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

#define tdesc   "Comedian Mail (Voicemail System)"

Definition at line 454 of file app_voicemail.c.

#define VM_ALLOCED   (1 << 13)

Definition at line 205 of file app_voicemail.c.

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

#define VM_ATTACH   (1 << 11)

Definition at line 203 of file app_voicemail.c.

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

#define VM_DELETE   (1 << 12)

Definition at line 204 of file app_voicemail.c.

Referenced by apply_option(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 202 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

Definition at line 196 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 200 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 199 of file app_voicemail.c.

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

#define VM_OPERATOR   (1 << 1)

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

Referenced by load_config(), and make_email_file().

#define VM_REVIEW   (1 << 0)

Definition at line 192 of file app_voicemail.c.

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

#define VM_SAYCID   (1 << 2)

Definition at line 194 of file app_voicemail.c.

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

#define VM_SAYDURATION   (1 << 5)

Definition at line 197 of file app_voicemail.c.

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

#define VM_SEARCH   (1 << 14)

Definition at line 206 of file app_voicemail.c.

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

#define VM_SKIPAFTERCMD   (1 << 6)

Definition at line 198 of file app_voicemail.c.

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

Definition at line 195 of file app_voicemail.c.

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

#define VM_TEMPGREETWARN   (1 << 15)

Remind user tempgreeting is set

Definition at line 207 of file app_voicemail.c.

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

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 168 of file app_voicemail.c.

#define VOICEMAIL_DIR_MODE   0777

Definition at line 164 of file app_voicemail.c.

Referenced by create_dirpath().

#define VOICEMAIL_FILE_MODE   0666

Definition at line 165 of file app_voicemail.c.

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


Enumeration Type Documentation

anonymous enum

Enumerator:
OPT_SILENT 
OPT_BUSY_GREETING 
OPT_UNAVAIL_GREETING 
OPT_RECORDGAIN 
OPT_PREPEND_MAILBOX 
OPT_PRIORITY_JUMP 
OPT_AUTOPLAY 

Definition at line 212 of file app_voicemail.c.

00212      {
00213    OPT_SILENT =           (1 << 0),
00214    OPT_BUSY_GREETING =    (1 << 1),
00215    OPT_UNAVAIL_GREETING = (1 << 2),
00216    OPT_RECORDGAIN =       (1 << 3),
00217    OPT_PREPEND_MAILBOX =  (1 << 4),
00218    OPT_PRIORITY_JUMP =    (1 << 5),
00219    OPT_AUTOPLAY =         (1 << 6),
00220 } vm_option_flags;

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_ARRAY_SIZE 

Definition at line 222 of file app_voicemail.c.

00222      {
00223    OPT_ARG_RECORDGAIN = 0,
00224    OPT_ARG_PLAYFOLDER = 1,
00225    /* This *must* be the last value in this enum! */
00226    OPT_ARG_ARRAY_SIZE = 2,
00227 } vm_option_args;


Function Documentation

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

Definition at line 3881 of file app_voicemail.c.

References ast_strlen_zero().

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

03882 {
03883    DIR *dir;
03884    struct dirent *de;
03885    char fn[256];
03886    int ret = 0;
03887    if (!folder)
03888       folder = "INBOX";
03889    /* If no mailbox, return immediately */
03890    if (ast_strlen_zero(mailbox))
03891       return 0;
03892    if (!context)
03893       context = "default";
03894    snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
03895    dir = opendir(fn);
03896    if (!dir)
03897       return 0;
03898    while ((de = readdir(dir))) {
03899       if (!strncasecmp(de->d_name, "msg", 3)) {
03900          if (shortcircuit) {
03901             ret = 1;
03902             break;
03903          } else if (!strncasecmp(de->d_name + 8, "txt", 3))
03904             ret++;
03905       }
03906    }
03907    closedir(dir);
03908    return ret;
03909 }

static void __reg_module ( void   )  [static]

Definition at line 9405 of file app_voicemail.c.

static void __unreg_module ( void   )  [static]

Definition at line 9405 of file app_voicemail.c.

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

Definition at line 4640 of file app_voicemail.c.

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

Referenced by vm_authenticate(), and vm_execmain().

04641 {
04642    int x;
04643    if (!ast_adsi_available(chan))
04644       return;
04645    x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
04646    if (x < 0)
04647       return;
04648    if (!x) {
04649       if (adsi_load_vmail(chan, useadsi)) {
04650          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
04651          return;
04652       }
04653    } else
04654       *useadsi = 1;
04655 }

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

Definition at line 4829 of file app_voicemail.c.

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

Referenced by vm_execmain().

04830 {
04831    int bytes=0;
04832    unsigned char buf[256];
04833    unsigned char keys[8];
04834 
04835    int x;
04836 
04837    if (!ast_adsi_available(chan))
04838       return;
04839 
04840    /* New meaning for keys */
04841    for (x=0;x<5;x++)
04842       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
04843 
04844    keys[6] = 0x0;
04845    keys[7] = 0x0;
04846 
04847    if (!vms->curmsg) {
04848       /* No prev key, provide "Folder" instead */
04849       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04850    }
04851    if (vms->curmsg >= vms->lastmsg) {
04852       /* If last message ... */
04853       if (vms->curmsg) {
04854          /* but not only message, provide "Folder" instead */
04855          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04856       } else {
04857          /* Otherwise if only message, leave blank */
04858          keys[3] = 1;
04859       }
04860    }
04861 
04862    /* If deleted, show "undeleted" */
04863    if (vms->deleted[vms->curmsg]) 
04864       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
04865 
04866    /* Except "Exit" */
04867    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
04868    bytes += ast_adsi_set_keys(buf + bytes, keys);
04869    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04870 
04871    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04872 }

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

Definition at line 4705 of file app_voicemail.c.

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

Referenced by vm_execmain().

04706 {
04707    unsigned char buf[256];
04708    int bytes=0;
04709    unsigned char keys[8];
04710    int x,y;
04711 
04712    if (!ast_adsi_available(chan))
04713       return;
04714 
04715    for (x=0;x<5;x++) {
04716       y = ADSI_KEY_APPS + 12 + start + x;
04717       if (y > ADSI_KEY_APPS + 12 + 4)
04718          y = 0;
04719       keys[x] = ADSI_KEY_SKT | y;
04720    }
04721    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
04722    keys[6] = 0;
04723    keys[7] = 0;
04724 
04725    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
04726    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
04727    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04728    bytes += ast_adsi_set_keys(buf + bytes, keys);
04729    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04730 
04731    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04732 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

Definition at line 4977 of file app_voicemail.c.

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

Referenced by vm_execmain().

04978 {
04979    unsigned char buf[256];
04980    int bytes=0;
04981 
04982    if (!ast_adsi_available(chan))
04983       return;
04984    bytes += adsi_logo(buf + bytes);
04985    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
04986    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
04987    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04988    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04989 
04990    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04991 }

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

Definition at line 4509 of file app_voicemail.c.

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

Referenced by adsi_begin().

04510 {
04511    unsigned char buf[256];
04512    int bytes=0;
04513    int x;
04514    char num[5];
04515 
04516    *useadsi = 0;
04517    bytes += ast_adsi_data_mode(buf + bytes);
04518    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04519 
04520    bytes = 0;
04521    bytes += adsi_logo(buf);
04522    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04523 #ifdef DISPLAY
04524    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
04525 #endif
04526    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04527    bytes += ast_adsi_data_mode(buf + bytes);
04528    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04529 
04530    if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
04531       bytes = 0;
04532       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
04533       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04534       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04535       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04536       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04537       return 0;
04538    }
04539 
04540 #ifdef DISPLAY
04541    /* Add a dot */
04542    bytes = 0;
04543    bytes += ast_adsi_logo(buf);
04544    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04545    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
04546    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04547    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04548 #endif
04549    bytes = 0;
04550    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
04551    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
04552    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
04553    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
04554    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
04555    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
04556    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04557 
04558 #ifdef DISPLAY
04559    /* Add another dot */
04560    bytes = 0;
04561    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
04562    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04563 
04564    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04565    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04566 #endif
04567 
04568    bytes = 0;
04569    /* These buttons we load but don't use yet */
04570    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
04571    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
04572    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
04573    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
04574    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
04575    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
04576    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04577 
04578 #ifdef DISPLAY
04579    /* Add another dot */
04580    bytes = 0;
04581    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
04582    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04583    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04584 #endif
04585 
04586    bytes = 0;
04587    for (x=0;x<5;x++) {
04588       snprintf(num, sizeof(num), "%d", x);
04589       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
04590    }
04591    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
04592    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04593 
04594 #ifdef DISPLAY
04595    /* Add another dot */
04596    bytes = 0;
04597    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
04598    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04599    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04600 #endif
04601 
04602    if (ast_adsi_end_download(chan)) {
04603       bytes = 0;
04604       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
04605       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04606       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04607       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04608       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04609       return 0;
04610    }
04611    bytes = 0;
04612    bytes += ast_adsi_download_disconnect(buf + bytes);
04613    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04614    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04615 
04616    if (option_debug)
04617       ast_log(LOG_DEBUG, "Done downloading scripts...\n");
04618 
04619 #ifdef DISPLAY
04620    /* Add last dot */
04621    bytes = 0;
04622    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
04623    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04624 #endif
04625    if (option_debug)
04626       ast_log(LOG_DEBUG, "Restarting session...\n");
04627 
04628    bytes = 0;
04629    /* Load the session now */
04630    if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
04631       *useadsi = 1;
04632       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
04633    } else
04634       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
04635 
04636    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04637    return 0;
04638 }

static void adsi_login ( struct ast_channel chan  )  [static]

Definition at line 4657 of file app_voicemail.c.

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

Referenced by vm_authenticate().

04658 {
04659    unsigned char buf[256];
04660    int bytes=0;
04661    unsigned char keys[8];
04662    int x;
04663    if (!ast_adsi_available(chan))
04664       return;
04665 
04666    for (x=0;x<8;x++)
04667       keys[x] = 0;
04668    /* Set one key for next */
04669    keys[3] = ADSI_KEY_APPS + 3;
04670 
04671    bytes += adsi_logo(buf + bytes);
04672    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
04673    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
04674    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04675    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
04676    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
04677    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
04678    bytes += ast_adsi_set_keys(buf + bytes, keys);
04679    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04680    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04681 }

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

Definition at line 4501 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, and ast_adsi_display().

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

04502 {
04503    int bytes = 0;
04504    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
04505    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
04506    return bytes;
04507 }

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

Definition at line 4734 of file app_voicemail.c.

References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), ast_copy_string(), ast_strlen_zero(), vm_state::curmsg, vm_state::fn, keys, and name.

Referenced by play_message(), and vm_execmain().

04735 {
04736    int bytes=0;
04737    unsigned char buf[256]; 
04738    char buf1[256], buf2[256];
04739    char fn2[PATH_MAX];
04740 
04741    char cid[256]="";
04742    char *val;
04743    char *name, *num;
04744    char datetime[21]="";
04745    FILE *f;
04746 
04747    unsigned char keys[8];
04748 
04749    int x;
04750 
04751    if (!ast_adsi_available(chan))
04752       return;
04753 
04754    /* Retrieve important info */
04755    snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
04756    f = fopen(fn2, "r");
04757    if (f) {
04758       while (!feof(f)) {   
04759          if (!fgets((char *)buf, sizeof(buf), f)) {
04760             continue;
04761          }
04762          if (!feof(f)) {
04763             char *stringp=NULL;
04764             stringp = (char *)buf;
04765             strsep(&stringp, "=");
04766             val = strsep(&stringp, "=");
04767             if (!ast_strlen_zero(val)) {
04768                if (!strcmp((char *)buf, "callerid"))
04769                   ast_copy_string(cid, val, sizeof(cid));
04770                if (!strcmp((char *)buf, "origdate"))
04771                   ast_copy_string(datetime, val, sizeof(datetime));
04772             }
04773          }
04774       }
04775       fclose(f);
04776    }
04777    /* New meaning for keys */
04778    for (x=0;x<5;x++)
04779       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
04780    keys[6] = 0x0;
04781    keys[7] = 0x0;
04782 
04783    if (!vms->curmsg) {
04784       /* No prev key, provide "Folder" instead */
04785       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04786    }
04787    if (vms->curmsg >= vms->lastmsg) {
04788       /* If last message ... */
04789       if (vms->curmsg) {
04790          /* but not only message, provide "Folder" instead */
04791          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04792          bytes += ast_adsi_voice_mode(buf + bytes, 0);
04793 
04794       } else {
04795          /* Otherwise if only message, leave blank */
04796          keys[3] = 1;
04797       }
04798    }
04799 
04800    if (!ast_strlen_zero(cid)) {
04801       ast_callerid_parse(cid, &name, &num);
04802       if (!name)
04803          name = num;
04804    } else
04805       name = "Unknown Caller";
04806 
04807    /* If deleted, show "undeleted" */
04808 
04809    if (vms->deleted[vms->curmsg])
04810       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
04811 
04812    /* Except "Exit" */
04813    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
04814    snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
04815       strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
04816    snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
04817 
04818    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04819    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04820    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
04821    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
04822    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04823    bytes += ast_adsi_set_keys(buf + bytes, keys);
04824    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04825 
04826    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04827 }

static void adsi_password ( struct ast_channel chan  )  [static]

Definition at line 4683 of file app_voicemail.c.

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

Referenced by vm_authenticate().

04684 {
04685    unsigned char buf[256];
04686    int bytes=0;
04687    unsigned char keys[8];
04688    int x;
04689    if (!ast_adsi_available(chan))
04690       return;
04691 
04692    for (x=0;x<8;x++)
04693       keys[x] = 0;
04694    /* Set one key for next */
04695    keys[3] = ADSI_KEY_APPS + 3;
04696 
04697    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04698    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
04699    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
04700    bytes += ast_adsi_set_keys(buf + bytes, keys);
04701    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04702    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04703 }

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

Definition at line 4874 of file app_voicemail.c.

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

Referenced by vm_execmain().

04875 {
04876    unsigned char buf[256] = "";
04877    char buf1[256] = "", buf2[256] = "";
04878    int bytes=0;
04879    unsigned char keys[8];
04880    int x;
04881 
04882    char *newm = (vms->newmessages == 1) ? "message" : "messages";
04883    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
04884    if (!ast_adsi_available(chan))
04885       return;
04886    if (vms->newmessages) {
04887       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
04888       if (vms->oldmessages) {
04889          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
04890          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
04891       } else {
04892          snprintf(buf2, sizeof(buf2), "%s.", newm);
04893       }
04894    } else if (vms->oldmessages) {
04895       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
04896       snprintf(buf2, sizeof(buf2), "%s.", oldm);
04897    } else {
04898       strcpy(buf1, "You have no messages.");
04899       buf2[0] = ' ';
04900       buf2[1] = '\0';
04901    }
04902    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04903    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04904    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04905 
04906    for (x=0;x<6;x++)
04907       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
04908    keys[6] = 0;
04909    keys[7] = 0;
04910 
04911    /* Don't let them listen if there are none */
04912    if (vms->lastmsg < 0)
04913       keys[0] = 1;
04914    bytes += ast_adsi_set_keys(buf + bytes, keys);
04915 
04916    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04917 
04918    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04919 }

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

Definition at line 4921 of file app_voicemail.c.

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

Referenced by vm_execmain().

04922 {
04923    unsigned char buf[256] = "";
04924    char buf1[256] = "", buf2[256] = "";
04925    int bytes=0;
04926    unsigned char keys[8];
04927    int x;
04928 
04929    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
04930 
04931    if (!ast_adsi_available(chan))
04932       return;
04933 
04934    /* Original command keys */
04935    for (x=0;x<6;x++)
04936       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
04937 
04938    keys[6] = 0;
04939    keys[7] = 0;
04940 
04941    if ((vms->lastmsg + 1) < 1)
04942       keys[0] = 0;
04943 
04944    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
04945       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
04946 
04947    if (vms->lastmsg + 1)
04948       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
04949    else
04950       strcpy(buf2, "no messages.");
04951    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04952    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04953    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
04954    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04955    bytes += ast_adsi_set_keys(buf + bytes, keys);
04956 
04957    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04958 
04959    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04960    
04961 }

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 9002 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(), make_file(), name, option_verbose, play_message_callerid(), play_message_datetime(), RETRIEVE, vm_state::starting, VERBOSE_PREFIX_3, and wait_file().

Referenced by vm_execmain().

09003 {
09004    int res = 0;
09005    char filename[PATH_MAX];
09006    struct ast_config *msg_cfg = NULL;
09007    const char *origtime, *context;
09008    char *cid, *name, *num;
09009    int retries = 0;
09010 
09011    vms->starting = 0; 
09012    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
09013 
09014    /* Retrieve info from VM attribute file */
09015    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
09016    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
09017    RETRIEVE(vms->curdir, vms->curmsg, vmu);
09018    msg_cfg = ast_config_load(filename);
09019    DISPOSE(vms->curdir, vms->curmsg);
09020    if (!msg_cfg) {
09021       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
09022       return 0;
09023    }
09024 
09025    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
09026       ast_config_destroy(msg_cfg);
09027       return 0;
09028    }
09029 
09030    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
09031 
09032    context = ast_variable_retrieve(msg_cfg, "message", "context");
09033    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
09034       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
09035    switch (option) {
09036    case 3:
09037       if (!res)
09038          res = play_message_datetime(chan, vmu, origtime, filename);
09039       if (!res)
09040          res = play_message_callerid(chan, vms, cid, context, 0);
09041 
09042       res = 't';
09043       break;
09044 
09045    case 2:  /* Call back */
09046 
09047       if (ast_strlen_zero(cid))
09048          break;
09049 
09050       ast_callerid_parse(cid, &name, &num);
09051       while ((res > -1) && (res != 't')) {
09052          switch (res) {
09053          case '1':
09054             if (num) {
09055                /* Dial the CID number */
09056                res = dialout(chan, vmu, num, vmu->callback);
09057                if (res) {
09058                   ast_config_destroy(msg_cfg);
09059                   return 9;
09060                }
09061             } else {
09062                res = '2';
09063             }
09064             break;
09065 
09066          case '2':
09067             /* Want to enter a different number, can only do this if there's a dialout context for this user */
09068             if (!ast_strlen_zero(vmu->dialout)) {
09069                res = dialout(chan, vmu, NULL, vmu->dialout);
09070                if (res) {
09071                   ast_config_destroy(msg_cfg);
09072                   return 9;
09073                }
09074             } else {
09075                if (option_verbose > 2)
09076                   ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
09077                res = ast_play_and_wait(chan, "vm-sorry");
09078             }
09079             ast_config_destroy(msg_cfg);
09080             return res;
09081          case '*':
09082             res = 't';
09083             break;
09084          case '3':
09085          case '4':
09086          case '5':
09087          case '6':
09088          case '7':
09089          case '8':
09090          case '9':
09091          case '0':
09092 
09093             res = ast_play_and_wait(chan, "vm-sorry");
09094             retries++;
09095             break;
09096          default:
09097             if (num) {
09098                if (option_verbose > 2)
09099                   ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
09100                res = ast_play_and_wait(chan, "vm-num-i-have");
09101                if (!res)
09102                   res = play_message_callerid(chan, vms, num, vmu->context, 1);
09103                if (!res)
09104                   res = ast_play_and_wait(chan, "vm-tocallnum");
09105                /* Only prompt for a caller-specified number if there is a dialout context specified */
09106                if (!ast_strlen_zero(vmu->dialout)) {
09107                   if (!res)
09108                      res = ast_play_and_wait(chan, "vm-calldiffnum");
09109                }
09110             } else {
09111                res = ast_play_and_wait(chan, "vm-nonumber");
09112                if (!ast_strlen_zero(vmu->dialout)) {
09113                   if (!res)
09114                      res = ast_play_and_wait(chan, "vm-toenternumber");
09115                }
09116             }
09117             if (!res)
09118                res = ast_play_and_wait(chan, "vm-star-cancel");
09119             if (!res)
09120                res = ast_waitfordigit(chan, 6000);
09121             if (!res) {
09122                retries++;
09123                if (retries > 3)
09124                   res = 't';
09125             }
09126             break; 
09127             
09128          }
09129          if (res == 't')
09130             res = 0;
09131          else if (res == '*')
09132             res = -1;
09133       }
09134       break;
09135       
09136    case 1:  /* Reply */
09137       /* Send reply directly to sender */
09138       if (ast_strlen_zero(cid))
09139          break;
09140 
09141       ast_callerid_parse(cid, &name, &num);
09142       if (!num) {
09143          if (option_verbose > 2)
09144             ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
09145          if (!res)
09146             res = ast_play_and_wait(chan, "vm-nonumber");
09147          ast_config_destroy(msg_cfg);
09148          return res;
09149       } else {
09150          struct ast_vm_user vmu2;
09151          if (find_user(&vmu2, vmu->context, num)) {
09152             struct leave_vm_options leave_options;
09153             char mailbox[AST_MAX_EXTENSION * 2 + 2];
09154             snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
09155 
09156             if (option_verbose > 2)
09157                ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
09158             
09159             memset(&leave_options, 0, sizeof(leave_options));
09160             leave_options.record_gain = record_gain;
09161             res = leave_voicemail(chan, mailbox, &leave_options);
09162             if (!res)
09163                res = 't';
09164             ast_config_destroy(msg_cfg);
09165             return res;
09166          } else {
09167             /* Sender has no mailbox, can't reply */
09168             if (option_verbose > 2)
09169                ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
09170             ast_play_and_wait(chan, "vm-nobox");
09171             res = 't';
09172             ast_config_destroy(msg_cfg);
09173             return res;
09174          }
09175       } 
09176       res = 0;
09177 
09178       break;
09179    }
09180 
09181 #ifndef IMAP_STORAGE
09182    ast_config_destroy(msg_cfg);
09183 
09184    if (!res) {
09185       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
09186       vms->heard[msg] = 1;
09187       res = wait_file(chan, vms, vms->fn);
09188    }
09189 #endif
09190    return res;
09191 }

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

Definition at line 8038 of file app_voicemail.c.

References apply_options(), ast_copy_string(), ast_strdupa, find_or_create(), populate_defaults(), and s.

Referenced by load_config().

08039 {
08040    /* Assumes lock is already held */
08041    char *tmp;
08042    char *stringp;
08043    char *s;
08044    struct ast_vm_user *vmu;
08045 
08046    tmp = ast_strdupa(data);
08047 
08048    if ((vmu = find_or_create(context, mbox))) {
08049       populate_defaults(vmu);
08050 
08051       stringp = tmp;
08052       if ((s = strsep(&stringp, ","))) 
08053          ast_copy_string(vmu->password, s, sizeof(vmu->password));
08054       if (stringp && (s = strsep(&stringp, ","))) 
08055          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
08056       if (stringp && (s = strsep(&stringp, ","))) 
08057          ast_copy_string(vmu->email, s, sizeof(vmu->email));
08058       if (stringp && (s = strsep(&stringp, ","))) 
08059          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
08060       if (stringp && (s = strsep(&stringp, ","))) 
08061          apply_options(vmu, s);
08062    }
08063    return 0;
08064 }

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

Definition at line 625 of file app_voicemail.c.

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

Referenced by apply_options(), and apply_options_full().

00626 {
00627    int x;
00628    if (!strcasecmp(var, "attach")) {
00629       ast_set2_flag(vmu, ast_true(value), VM_ATTACH);
00630    } else if (!strcasecmp(var, "attachfmt")) {
00631       ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt));
00632    } else if (!strcasecmp(var, "preprocesscmd")) {
00633       ast_copy_string(vmu->preprocesscmd, value, sizeof(vmu->preprocesscmd));
00634    } else if (!strcasecmp(var, "preprocessfmt")) {
00635       ast_copy_string(vmu->preprocessfmt, value, sizeof(vmu->preprocessfmt));
00636    } else if (!strcasecmp(var, "serveremail")) {
00637       ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail));
00638    } else if (!strcasecmp(var, "language")) {
00639       ast_copy_string(vmu->language, value, sizeof(vmu->language));
00640    } else if (!strcasecmp(var, "tz")) {
00641       ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
00642 #ifdef IMAP_STORAGE
00643    } else if (!strcasecmp(var, "imapuser")) {
00644       ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser));
00645       vmu->imapversion = imapversion;
00646    } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) {
00647       ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword));
00648       vmu->imapversion = imapversion;
00649    } else if (!strcasecmp(var, "imapvmshareid")) {
00650       ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid));
00651       vmu->imapversion = imapversion;
00652 #endif
00653    } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
00654       ast_set2_flag(vmu, ast_true(value), VM_DELETE); 
00655    } else if (!strcasecmp(var, "saycid")){
00656       ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 
00657    } else if (!strcasecmp(var,"sendvoicemail")){
00658       ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 
00659    } else if (!strcasecmp(var, "review")){
00660       ast_set2_flag(vmu, ast_true(value), VM_REVIEW);
00661    } else if (!strcasecmp(var, "tempgreetwarn")){
00662       ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN);   
00663    } else if (!strcasecmp(var, "operator")){
00664       ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);  
00665    } else if (!strcasecmp(var, "envelope")){
00666       ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE);  
00667    } else if (!strcasecmp(var, "sayduration")){
00668       ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION);  
00669    } else if (!strcasecmp(var, "saydurationm")){
00670       if (sscanf(value, "%30d", &x) == 1) {
00671          vmu->saydurationm = x;
00672       } else {
00673          ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
00674       }
00675    } else if (!strcasecmp(var, "forcename")){
00676       ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 
00677    } else if (!strcasecmp(var, "forcegreetings")){
00678       ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET);   
00679    } else if (!strcasecmp(var, "callback")) {
00680       ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
00681    } else if (!strcasecmp(var, "dialout")) {
00682       ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout));
00683    } else if (!strcasecmp(var, "exitcontext")) {
00684       ast_copy_string(vmu->exit, value, sizeof(vmu->exit));
00685    } else if (!strcasecmp(var, "maxmsg")) {
00686       vmu->maxmsg = atoi(value);
00687       if (vmu->maxmsg <= 0) {
00688          ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %i\n", value, MAXMSG);
00689          vmu->maxmsg = MAXMSG;
00690       } else if (vmu->maxmsg > MAXMSGLIMIT) {
00691          ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value);
00692          vmu->maxmsg = MAXMSGLIMIT;
00693       }
00694    } else if (!strcasecmp(var, "volgain")) {
00695       sscanf(value, "%30lf", &vmu->volgain);
00696    } else if (!strcasecmp(var, "options")) {
00697       apply_options(vmu, value);
00698    }
00699 }

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

Definition at line 716 of file app_voicemail.c.

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

Referenced by append_mailbox(), and apply_option().

00717 {  /* Destructively Parse options and apply */
00718    char *stringp;
00719    char *s;
00720    char *var, *value;
00721    stringp = ast_strdupa(options);
00722    while ((s = strsep(&stringp, "|"))) {
00723       value = s;
00724       if ((var = strsep(&value, "=")) && value) {
00725          apply_option(vmu, var, value);
00726       }
00727    }  
00728 }

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

Definition at line 730 of file app_voicemail.c.

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

Referenced by find_user_realtime(), and load_config().

00731 {
00732    struct ast_variable *tmp;
00733    tmp = var;
00734    while (tmp) {
00735       if (!strcasecmp(tmp->name, "vmsecret")) {
00736          ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00737       } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
00738          if (ast_strlen_zero(retval->password))
00739             ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00740       } else if (!strcasecmp(tmp->name, "uniqueid")) {
00741          ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00742       } else if (!strcasecmp(tmp->name, "pager")) {
00743          ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00744       } else if (!strcasecmp(tmp->name, "email")) {
00745          ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00746       } else if (!strcasecmp(tmp->name, "fullname")) {
00747          ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00748       } else if (!strcasecmp(tmp->name, "context")) {
00749          ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00750 #ifdef IMAP_STORAGE
00751       } else if (!strcasecmp(tmp->name, "imapuser")) {
00752          ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
00753          retval->imapversion = imapversion;
00754       } else if (!strcasecmp(tmp->name, "imappassword") || !strcasecmp(tmp->name, "imapsecret")) {
00755          ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
00756          retval->imapversion = imapversion;
00757       } else if (!strcasecmp(tmp->name, "imapvmshareid")) {
00758          ast_copy_string(retval->imapvmshareid, tmp->value, sizeof(retval->imapvmshareid));
00759          retval->imapversion = imapversion;
00760 #endif
00761       } else
00762          apply_option(retval, tmp->name, tmp->value);
00763       tmp = tmp->next;
00764    } 
00765 }

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

Definition at line 2953 of file app_voicemail.c.

References ast_log(), BASEMAXINLINE, eol, errno, inchar(), and ochar().

Referenced by make_email_file().

02954 {
02955    unsigned char dtable[BASEMAXINLINE];
02956    int i,hiteof= 0;
02957    FILE *fi;
02958    struct baseio bio;
02959 
02960    memset(&bio, 0, sizeof(bio));
02961    bio.iocp = BASEMAXINLINE;
02962 
02963    if (!(fi = fopen(filename, "rb"))) {
02964       ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
02965       return -1;
02966    }
02967 
02968    for (i= 0;i<9;i++) {
02969       dtable[i]= 'A'+i;
02970       dtable[i+9]= 'J'+i;
02971       dtable[26+i]= 'a'+i;
02972       dtable[26+i+9]= 'j'+i;
02973    }
02974    for (i= 0;i<8;i++) {
02975       dtable[i+18]= 'S'+i;
02976       dtable[26+i+18]= 's'+i;
02977    }
02978    for (i= 0;i<10;i++) {
02979       dtable[52+i]= '0'+i;
02980    }
02981    dtable[62]= '+';
02982    dtable[63]= '/';
02983 
02984    while (!hiteof){
02985       unsigned char igroup[3],ogroup[4];
02986       int c,n;
02987 
02988       igroup[0]= igroup[1]= igroup[2]= 0;
02989 
02990       for (n= 0;n<3;n++) {
02991          if ((c = inchar(&bio, fi)) == EOF) {
02992             hiteof= 1;
02993             break;
02994          }
02995 
02996          igroup[n]= (unsigned char)c;
02997       }
02998 
02999       if (n> 0) {
03000          ogroup[0]= dtable[igroup[0]>>2];
03001          ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)];
03002          ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)];
03003          ogroup[3]= dtable[igroup[2]&0x3F];
03004 
03005          if (n<3) {
03006             ogroup[3]= '=';
03007 
03008             if (n<2)
03009                ogroup[2]= '=';
03010          }
03011 
03012          for (i= 0;i<4;i++)
03013             ochar(&bio, ogroup[i], so);
03014       }
03015    }
03016 
03017    fclose(fi);
03018    
03019    if (fputs(eol,so)==EOF)
03020       return 0;
03021 
03022    return 1;
03023 }

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

Definition at line 701 of file app_voicemail.c.

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

Referenced by vm_change_password().

00702 {
00703    int res = -1;
00704    if (!strcmp(vmu->password, password)) {
00705       /* No change (but an update would return 0 rows updated, so we opt out here) */
00706       res = 0;
00707    } else if (!ast_strlen_zero(vmu->uniqueid)) {
00708       if (ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL) > 0) {
00709          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00710          res = 0;
00711       }
00712    }
00713    return res;
00714 }

static int check_mime ( const char *  str  )  [static]

Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean.

Definition at line 3121 of file app_voicemail.c.

Referenced by make_email_file().

03122 {
03123    for (; *str; str++) {
03124       if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
03125          return 1;
03126       }
03127    }
03128    return 0;
03129 }

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

Definition at line 5818 of file app_voicemail.c.

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

Referenced by vm_execmain().

05819 {
05820    int x = 0;
05821 #ifndef IMAP_STORAGE
05822    int res = 0, nummsg;
05823 #endif
05824 
05825    if (vms->lastmsg <= -1)
05826       goto done;
05827 
05828    vms->curmsg = -1; 
05829 #ifndef IMAP_STORAGE
05830    /* Get the deleted messages fixed */ 
05831    if (vm_lock_path(vms->curdir))
05832       return ERROR_LOCK_PATH;
05833     
05834    for (x = 0; x < vmu->maxmsg; x++) { 
05835       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
05836          /* Save this message.  It's not in INBOX or hasn't been heard */ 
05837          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
05838          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
05839             break;
05840          vms->curmsg++; 
05841          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
05842          if (strcmp(vms->fn, vms->fn2)) { 
05843             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
05844          } 
05845       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
05846          /* Move to old folder before deleting */ 
05847          res = save_to_folder(vmu, vms, x, 1);
05848          if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) {
05849             /* If save failed do not delete the message */
05850             ast_log(LOG_WARNING, "Save failed.  Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
05851             vms->deleted[x] = 0;
05852             vms->heard[x] = 0;
05853             --x;
05854          } 
05855       } 
05856    } 
05857 
05858    /* Delete ALL remaining messages */
05859    nummsg = x - 1;
05860    for (x = vms->curmsg + 1; x <= nummsg; x++) {
05861       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
05862       if (EXISTS(vms->curdir, x, vms->fn, NULL))
05863          DELETE(vms->curdir, x, vms->fn, vmu);
05864    }
05865    ast_unlock_path(vms->curdir);
05866 #else
05867    if (vms->deleted) {
05868       for (x=0;x < vmu->maxmsg;x++) { 
05869          if (vms->deleted[x]) { 
05870             if (option_debug > 2)
05871                ast_log(LOG_DEBUG,"IMAP delete of %d\n",x);
05872             DELETE(vms->curdir, x, vms->fn, vmu);
05873          }
05874       }
05875    }
05876 #endif
05877 
05878 done:
05879    if (vms->deleted)
05880       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
05881    if (vms->heard)
05882       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
05883 
05884    return 0;
05885 }

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

Definition at line 8227 of file app_voicemail.c.

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

08228 {
08229    int which = 0;
08230    int wordlen;
08231    struct ast_vm_user *vmu;
08232    const char *context = "";
08233 
08234    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
08235    if (pos > 4)
08236       return NULL;
08237    if (pos == 3)
08238       return (state == 0) ? ast_strdup("for") : NULL;
08239    wordlen = strlen(word);
08240    AST_LIST_TRAVERSE(&users, vmu, list) {
08241       if (!strncasecmp(word, vmu->context, wordlen)) {
08242          if (context && strcmp(context, vmu->context) && ++which > state)
08243             return ast_strdup(vmu->context);
08244          /* ignore repeated contexts ? */
08245          context = vmu->context;
08246       }
08247    }
08248    return NULL;
08249 }

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

Definition at line 2831 of file app_voicemail.c.

References ast_log(), errno, and VOICEMAIL_FILE_MODE.

02832 {
02833    int ifd;
02834    int ofd;
02835    int res;
02836    int len;
02837    char buf[4096];
02838 
02839 #ifdef HARDLINK_WHEN_POSSIBLE
02840    /* Hard link if possible; saves disk space & is faster */
02841    if (link(infile, outfile)) {
02842 #endif
02843       if ((ifd = open(infile, O_RDONLY)) < 0) {
02844          ast_log(LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno));
02845          return -1;
02846       }
02847       if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
02848          ast_log(LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno));
02849          close(ifd);
02850          return -1;
02851       }
02852       do {
02853          len = read(ifd, buf, sizeof(buf));
02854          if (len < 0) {
02855             ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
02856             close(ifd);
02857             close(ofd);
02858             unlink(outfile);
02859          }
02860          if (len) {
02861             res = write(ofd, buf, len);
02862             if (errno == ENOMEM || errno == ENOSPC || res != len) {
02863                ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
02864                close(ifd);
02865                close(ofd);
02866                unlink(outfile);
02867             }
02868          }
02869       } while (len);
02870       close(ifd);
02871       close(ofd);
02872       return 0;
02873 #ifdef HARDLINK_WHEN_POSSIBLE
02874    } else {
02875       /* Hard link succeeded */
02876       return 0;
02877    }
02878 #endif
02879 }

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

References ast_copy_string(), ast_log(), ast_unlock_path(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, COPY, copy_plain_file(), 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(), S_OR, STORE, vm_delete(), and vm_lock_path().

Referenced by forward_message(), and leave_voicemail().

03826 {
03827    char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
03828    const char *frombox = mbox(imbox);
03829    int recipmsgnum;
03830 
03831    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
03832 
03833    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
03834    
03835    if (!dir)
03836       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
03837    else
03838       ast_copy_string(fromdir, dir, sizeof(fromdir));
03839 
03840    make_file(frompath, sizeof(frompath), fromdir, msgnum);
03841 
03842    if (vm_lock_path(todir))
03843       return ERROR_LOCK_PATH;
03844 
03845    recipmsgnum = 0;
03846    do {
03847       make_file(topath, sizeof(topath), todir, recipmsgnum);
03848       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
03849          break;
03850       recipmsgnum++;
03851    } while (recipmsgnum < recip->maxmsg);
03852    if (recipmsgnum < recip->maxmsg) {
03853       if (EXISTS(fromdir, msgnum, frompath, chan->language)) {
03854          COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
03855       } else {
03856          /* For ODBC storage, if the file we want to copy isn't yet in the database, then the SQL
03857           * copy will fail. Instead, we need to create a local copy, store it, and delete the local
03858           * copy. We don't have to #ifdef this because if file storage reaches this point, there's a
03859           * much worse problem happening and IMAP storage doesn't call this function
03860           */
03861          copy_plain_file(frompath, topath);
03862          STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL);
03863          vm_delete(topath);
03864       }
03865    } else {
03866       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
03867    }
03868    ast_unlock_path(todir);
03869    notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
03870    
03871    return 0;
03872 }

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

Definition at line 2881 of file app_voicemail.c.

References ast_filecopy(), and copy().

Referenced by copy_message(), and forward_message().

02882 {
02883    char frompath2[PATH_MAX], topath2[PATH_MAX];
02884    ast_filecopy(frompath, topath, NULL);
02885    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
02886    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
02887    copy(frompath2, topath2);
02888 }

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

Definition at line 2747 of file app_voicemail.c.

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

Referenced by leave_voicemail(), and open_mailbox().

02748 {
02749    /* Find all .txt files - even if they are not in sequence from 0000 */
02750 
02751    int vmcount = 0;
02752    DIR *vmdir = NULL;
02753    struct dirent *vment = NULL;
02754 
02755    if (vm_lock_path(dir))
02756       return ERROR_LOCK_PATH;
02757 
02758    if ((vmdir = opendir(dir))) {
02759       while ((vment = readdir(vmdir))) {
02760          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
02761             vmcount++;
02762       }
02763       closedir(vmdir);
02764    }
02765    ast_unlock_path(dir);
02766    
02767    return vmcount;
02768 }

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

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

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

Definition at line 968 of file app_voicemail.c.

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

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

00969 {
00970    mode_t   mode = VOICEMAIL_DIR_MODE;
00971 
00972    if (!ast_strlen_zero(context)) {
00973       make_dir(dest, len, context, "", "");
00974       if (mkdir(dest, mode) && errno != EEXIST) {
00975          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00976          return -1;
00977       }
00978    }
00979    if (!ast_strlen_zero(ext)) {
00980       make_dir(dest, len, context, ext, "");
00981       if (mkdir(dest, mode) && errno != EEXIST) {
00982          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00983          return -1;
00984       }
00985    }
00986    if (!ast_strlen_zero(folder)) {
00987       make_dir(dest, len, context, ext, folder);
00988       if (mkdir(dest, mode) && errno != EEXIST) {
00989          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00990          return -1;
00991       }
00992    }
00993    return 0;
00994 }

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

Definition at line 8941 of file app_voicemail.c.

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

08942 {
08943    int cmd = 0;
08944    char destination[80] = "";
08945    int retries = 0;
08946 
08947    if (!num) {
08948       if (option_verbose > 2)
08949          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
08950       while (retries < 3 && cmd != 't') {
08951          destination[1] = '\0';
08952          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
08953          if (!cmd)
08954             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
08955          if (!cmd)
08956             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
08957          if (!cmd) {
08958             cmd = ast_waitfordigit(chan, 6000);
08959             if (cmd)
08960                destination[0] = cmd;
08961          }
08962          if (!cmd) {
08963             retries++;
08964          } else {
08965 
08966             if (cmd < 0)
08967                return 0;
08968             if (cmd == '*') {
08969                if (option_verbose > 2)
08970                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
08971                return 0;
08972             }
08973             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
08974                retries++;
08975             else
08976                cmd = 't';
08977          }
08978       }
08979       if (retries >= 3) {
08980          return 0;
08981       }
08982       
08983    } else {
08984       if (option_verbose > 2)
08985          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
08986       ast_copy_string(destination, num, sizeof(destination));
08987    }
08988 
08989    if (!ast_strlen_zero(destination)) {
08990       if (destination[strlen(destination) -1 ] == '*')
08991          return 0; 
08992       if (option_verbose > 2)
08993          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
08994       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
08995       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
08996       chan->priority = 0;
08997       return 9;
08998    }
08999    return 0;
09000 }

static char* encode_mime_str ( const char *  start,
char *  end,
size_t  endsize,
size_t  preamble,
size_t  postamble 
) [static]

Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters.

Additionally, if the encoded string would exceed the MIME limit of 76 characters per line, then the encoding will be broken up into multiple sections, separated by a space character, in order to facilitate breaking up the associated header across multiple lines.

Parameters:
start A string to be encoded
end An expandable buffer for holding the result
preamble The length of the first line already used for this string, to ensure that each line maintains a maximum length of 76 chars.
postamble the length of any additional characters appended to the line, used to ensure proper field wrapping.
Return values:
The encoded string.

Definition at line 3147 of file app_voicemail.c.

Referenced by make_email_file().

03148 {
03149    char tmp[80];
03150    int first_section = 1;
03151    size_t endlen = 0, tmplen = 0;
03152    *end = '\0';
03153 
03154    tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03155    for (; *start; start++) {
03156       int need_encoding = 0;
03157       if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) {
03158          need_encoding = 1;
03159       }
03160       if ((first_section && need_encoding && preamble + tmplen > 70) ||
03161          (first_section && !need_encoding && preamble + tmplen > 72) ||
03162          (!first_section && need_encoding && tmplen > 70) ||
03163          (!first_section && !need_encoding && tmplen > 72)) {
03164          /* Start new line */
03165          endlen += snprintf(end + endlen, endsize - endlen, "%s%s?=", first_section ? "" : " ", tmp);
03166          tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03167          first_section = 0;
03168       }
03169       if (need_encoding && *start == ' ') {
03170          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "_");
03171       } else if (need_encoding) {
03172          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "=%hhX", *start);
03173       } else {
03174          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%c", *start);
03175       }
03176    }
03177    snprintf(end + endlen, endsize - endlen, "%s%s?=%s", first_section ? "" : " ", tmp, endlen + postamble > 74 ? " " : "");
03178    return end;
03179 }

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

Definition at line 8010 of file app_voicemail.c.

References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_test_flag, ast_vm_user::context, globalflags, ast_vm_user::list, ast_vm_user::mailbox, and VM_SEARCH.

Referenced by append_mailbox(), and load_config().

08011 {
08012    struct ast_vm_user *vmu;
08013    AST_LIST_TRAVERSE(&users, vmu, list) {
08014       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox)) {
08015          if (strcasecmp(vmu->context, context)) {
08016             ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\
08017                   \n\tcontexts and that you have the 'searchcontexts' option on. This type of\
08018                   \n\tconfiguration creates an ambiguity that you likely do not want. Please\
08019                   \n\tamend your voicemail.conf file to avoid this situation.\n", mbox);
08020          }
08021          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", mbox);
08022          return NULL;
08023       }
08024       if (!strcasecmp(context, vmu->context) && !strcasecmp(mbox, vmu->mailbox)) {
08025          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", mbox, context);
08026          return NULL;
08027       }
08028    }
08029    
08030    if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
08031       ast_copy_string(vmu->context, context, sizeof(vmu->context));
08032       ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
08033       AST_LIST_INSERT_TAIL(&users, vmu, list);
08034    }
08035    return vmu;
08036 }

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

Definition at line 796 of file app_voicemail.c.

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

00797 {
00798    /* This function could be made to generate one from a database, too */
00799    struct ast_vm_user *vmu=NULL, *cur;
00800    AST_LIST_LOCK(&users);
00801 
00802    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00803       context = "default";
00804 
00805    AST_LIST_TRAVERSE(&users, cur, list) {
00806 #ifdef IMAP_STORAGE
00807       if (cur->imapversion != imapversion) {
00808          continue;
00809       }
00810 #endif
00811       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00812          break;
00813       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00814          break;
00815    }
00816    if (cur) {
00817       /* Make a copy, so that on a reload, we have no race */
00818       if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
00819          memcpy(vmu, cur, sizeof(*vmu));
00820          ast_set2_flag(vmu, !ivm, VM_ALLOCED);
00821          AST_LIST_NEXT(vmu, list) = NULL;
00822       }
00823    } else
00824       vmu = find_user_realtime(ivm, context, mailbox);
00825    AST_LIST_UNLOCK(&users);
00826    return vmu;
00827 }

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

Definition at line 767 of file app_voicemail.c.

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

Referenced by find_user().

00768 {
00769    struct ast_variable *var;
00770    struct ast_vm_user *retval;
00771 
00772    if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
00773       if (!ivm)
00774          ast_set_flag(retval, VM_ALLOCED);   
00775       else
00776          memset(retval, 0, sizeof(*retval));
00777       if (mailbox) 
00778          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00779       populate_defaults(retval);
00780       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00781          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00782       else
00783          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00784       if (var) {
00785          apply_options_full(retval, var);
00786          ast_variables_destroy(var);
00787       } else { 
00788          if (!ivm) 
00789             free(retval);
00790          retval = NULL;
00791       }  
00792    } 
00793    return retval;
00794 }

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

Definition at line 5199 of file app_voicemail.c.

References app, ast_clear_flag, ast_copy_string(), AST_LIST_EMPTY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, ast_channel::context, copy_message(), copy_plain_file(), create_dirpath(), vm_state::curbox, vm_state::curdir, vm_state::curmsg, DISPOSE, ast_channel::exten, find_user(), vm_state::fn, free_user(), globalflags, ast_channel::language, leave_voicemail(), ast_app::list, LOG_ERROR, LOG_NOTICE, ast_vm_user::mailbox, make_file(), pbx_exec(), pbx_findapp(), ast_channel::priority, RETRIEVE, run_externnotify(), s, S_OR, sendmail(), STORE, username, VM_ATTACH, vm_delete(), VM_DIRECFORWARD, and vm_forwardoptions().

Referenced by vm_execmain().

05200 {
05201 #ifdef IMAP_STORAGE
05202    int todircount=0;
05203    struct vm_state *dstvms;
05204 #endif
05205    char username[70]="";
05206    int res = 0, cmd = 0;
05207    struct ast_vm_user *receiver = NULL, *vmtmp;
05208    AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
05209    char *stringp;
05210    const char *s;
05211    int saved_messages = 0, found = 0;
05212    int valid_extensions = 0;
05213    char *dir;
05214    int curmsg;
05215 
05216    if (vms == NULL) return -1;
05217    dir = vms->curdir;
05218    curmsg = vms->curmsg;
05219    
05220    while (!res && !valid_extensions) {
05221       int use_directory = 0;
05222       if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
05223          int done = 0;
05224          int retries = 0;
05225          cmd=0;
05226          while ((cmd >= 0) && !done ){
05227             if (cmd)
05228                retries = 0;
05229             switch (cmd) {
05230             case '1': 
05231                use_directory = 0;
05232                done = 1;
05233                break;
05234             case '2': 
05235                use_directory = 1;
05236                done=1;
05237                break;
05238             case '*': 
05239                cmd = 't';
05240                done = 1;
05241                break;
05242             default: 
05243                /* Press 1 to enter an extension press 2 to use the directory */
05244                cmd = ast_play_and_wait(chan,"vm-forward");
05245                if (!cmd)
05246                   cmd = ast_waitfordigit(chan,3000);
05247                if (!cmd)
05248                   retries++;
05249                if (retries > 3)
05250                {
05251                   cmd = 't';
05252                   done = 1;
05253                }
05254                
05255             }
05256          }
05257          if (cmd < 0 || cmd == 't')
05258             break;
05259       }
05260       
05261       if (use_directory) {
05262          /* use app_directory */
05263          
05264          char old_context[sizeof(chan->context)];
05265          char old_exten[sizeof(chan->exten)];
05266          int old_priority;
05267          struct ast_app* app;
05268 
05269          
05270          app = pbx_findapp("Directory");
05271          if (app) {
05272             char vmcontext[256];
05273             /* make backup copies */
05274             memcpy(old_context, chan->context, sizeof(chan->context));
05275             memcpy(old_exten, chan->exten, sizeof(chan->exten));
05276             old_priority = chan->priority;
05277             
05278             /* call the the Directory, changes the channel */
05279             snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default");
05280             res = pbx_exec(chan, app, vmcontext);
05281             
05282             ast_copy_string(username, chan->exten, sizeof(username));
05283             
05284             /* restore the old context, exten, and priority */
05285             memcpy(chan->context, old_context, sizeof(chan->context));
05286             memcpy(chan->exten, old_exten, sizeof(chan->exten));
05287             chan->priority = old_priority;
05288             
05289          } else {
05290             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
05291             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
05292          }
05293       } else {
05294          /* Ask for an extension */
05295          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
05296          if (res)
05297             break;
05298          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
05299             break;
05300       }
05301       
05302       /* start all over if no username */
05303       if (ast_strlen_zero(username))
05304          continue;
05305       stringp = username;
05306       s = strsep(&stringp, "*");
05307       /* start optimistic */
05308       valid_extensions = 1;
05309       while (s) {
05310          /* Don't forward to ourselves but allow leaving a message for ourselves (flag == 1).  find_user is going to malloc since we have a NULL as first argument */
05311          if ((flag == 1 || strcmp(s,sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
05312             AST_LIST_INSERT_HEAD(&extensions, receiver, list);
05313             found++;
05314          } else {
05315             ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s);
05316             valid_extensions = 0;
05317             break;
05318          }
05319          s = strsep(&stringp, "*");
05320       }
05321       /* break from the loop of reading the extensions */
05322       if (valid_extensions)
05323          break;
05324       /* "I am sorry, that's not a valid extension.  Please try again." */
05325       res = ast_play_and_wait(chan, "pbx-invalid");
05326    }
05327    /* check if we're clear to proceed */
05328    if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
05329       return res;
05330    if (flag==1) {
05331       struct leave_vm_options leave_options;
05332       char mailbox[AST_MAX_EXTENSION * 2 + 2];
05333       /* Make sure that context doesn't get set as a literal "(null)" (or else find_user won't find it) */
05334       if (context)
05335          snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
05336       else
05337          ast_copy_string(mailbox, username, sizeof(mailbox));
05338 
05339       /* Send VoiceMail */
05340       memset(&leave_options, 0, sizeof(leave_options));
05341       leave_options.record_gain = record_gain;
05342       cmd = leave_voicemail(chan, mailbox, &leave_options);
05343    } else {
05344       /* Forward VoiceMail */
05345       long duration = 0;
05346       char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
05347       struct vm_state vmstmp;
05348 
05349       memcpy(&vmstmp, vms, sizeof(vmstmp));
05350 
05351       make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
05352       create_dirpath(vmstmp.curdir, sizeof(vmstmp.curdir), sender->context, vmstmp.username, "tmp");
05353       make_file(msgfile, sizeof(msgfile), vmstmp.curdir, curmsg);
05354 
05355       RETRIEVE(dir, curmsg, sender);
05356 
05357       /* Alter a surrogate file, only */
05358       copy_plain_file(origmsgfile, msgfile);
05359 
05360       cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp);
05361       if (!cmd) {
05362          AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
05363 #ifdef IMAP_STORAGE
05364             char *myserveremail;
05365             int attach_user_voicemail;
05366             /* get destination mailbox */
05367             dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0);
05368             if (!dstvms) {
05369                dstvms = create_vm_state_from_user(vmtmp);
05370             }
05371             if (dstvms) {
05372                init_mailstream(dstvms, 0);
05373                if (!dstvms->mailstream) {
05374                   ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
05375                } else {
05376                   STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
05377                   run_externnotify(vmtmp->context, vmtmp->mailbox); 
05378                }
05379             } else {
05380                ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
05381             }
05382             myserveremail = serveremail;
05383             if (!ast_strlen_zero(vmtmp->serveremail))
05384                myserveremail = vmtmp->serveremail;
05385             attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
05386             /* NULL category for IMAP storage */
05387             sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, dstvms->curbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vms->fn, fmt, duration, attach_user_voicemail, chan, NULL);
05388 #else
05389             copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir);
05390 #endif
05391             saved_messages++;
05392             AST_LIST_REMOVE_CURRENT(&extensions, list);
05393             free_user(vmtmp);
05394             if (res)
05395                break;
05396          }
05397          AST_LIST_TRAVERSE_SAFE_END;
05398          if (saved_messages > 0) {
05399             /* give confirmation that the message was saved */
05400             /* commented out since we can't forward batches yet
05401             if (saved_messages == 1)
05402                res = ast_play_and_wait(chan, "vm-message");
05403             else
05404                res = ast_play_and_wait(chan, "vm-messages");
05405             if (!res)
05406                res = ast_play_and_wait(chan, "vm-saved"); */
05407             res = ast_play_and_wait(chan, "vm-msgsaved");
05408          }  
05409       }
05410 
05411       /* Remove surrogate file */
05412       vm_delete(msgfile);
05413       DISPOSE(dir, curmsg);
05414    }
05415 
05416    /* If anything failed above, we still have this list to free */
05417    while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list)))
05418       free_user(vmtmp);
05419    return res ? res : cmd;
05420 }

static void free_user ( struct ast_vm_user vmu  )  [static]

Definition at line 1013 of file app_voicemail.c.

References ast_test_flag, free, and VM_ALLOCED.

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

01014 {
01015    if (ast_test_flag(vmu, VM_ALLOCED))
01016       free(vmu);
01017 }

static void free_vm_users ( void   )  [static]

Definition at line 8271 of file app_voicemail.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_set_flag, free_user(), free_zone(), vm_zone::list, and VM_ALLOCED.

Referenced by load_config().

08272 {
08273    struct ast_vm_user *cur;
08274    struct vm_zone *zcur;
08275 
08276    AST_LIST_LOCK(&users);
08277    while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
08278       ast_set_flag(cur, VM_ALLOCED);
08279       free_user(cur);
08280    }
08281    AST_LIST_UNLOCK(&users);
08282 
08283    AST_LIST_LOCK(&zones);
08284    while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) {
08285       free_zone(zcur);
08286    }
08287    AST_LIST_UNLOCK(&zones);
08288 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 3668 of file app_voicemail.c.

References free.

03669 {
03670    free(z);
03671 }

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

Definition at line 3601 of file app_voicemail.c.

References ast_localtime().

Referenced by leave_voicemail(), and tds_log().

03602 {
03603    struct tm tm;
03604    time_t t;
03605 
03606    time(&t);
03607 
03608    ast_localtime(&t, &tm, NULL);
03609 
03610    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
03611 }

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

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

04998 {
04999    int x;
05000    int d;
05001    char fn[PATH_MAX];
05002    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
05003    if (d)
05004       return d;
05005    for (x = start; x< 5; x++) {  /* For all folders */
05006       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
05007          return d;
05008       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
05009       if (d)
05010          return d;
05011       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
05012       d = vm_play_folder_name(chan, fn);
05013       if (d)
05014          return d;
05015       d = ast_waitfordigit(chan, 500);
05016       if (d)
05017          return d;
05018    }
05019    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
05020    if (d)
05021       return d;
05022    d = ast_waitfordigit(chan, 4000);
05023    return d;
05024 }

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

Definition at line 5026 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

05027 {
05028    int res = 0;
05029    res = ast_play_and_wait(chan, fn);  /* Folder name */
05030    while (((res < '0') || (res > '9')) &&
05031          (res != '#') && (res >= 0)) {
05032       res = get_folder(chan, 0);
05033    }
05034    return res;
05035 }

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

Definition at line 8157 of file app_voicemail.c.

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

08158 {
08159    struct ast_vm_user *vmu;
08160    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
08161 
08162    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
08163    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
08164 
08165    AST_LIST_LOCK(&users);
08166    if (!AST_LIST_EMPTY(&users)) {
08167       if (argc == 3)
08168          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08169       else {
08170          int count = 0;
08171          AST_LIST_TRAVERSE(&users, vmu, list) {
08172             if (!strcmp(argv[4],vmu->context))
08173                count++;
08174          }
08175          if (count) {
08176             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08177          } else {
08178             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
08179             AST_LIST_UNLOCK(&users);
08180             return RESULT_FAILURE;
08181          }
08182       }
08183       AST_LIST_TRAVERSE(&users, vmu, list) {
08184          int newmsgs = 0, oldmsgs = 0;
08185          char count[12], tmp[256] = "";
08186 
08187          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
08188             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
08189             inboxcount(tmp, &newmsgs, &oldmsgs);
08190             snprintf(count,sizeof(count),"%d",newmsgs);
08191             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
08192          }
08193       }
08194    } else {
08195       ast_cli(fd, "There are no voicemail users currently defined\n");
08196       AST_LIST_UNLOCK(&users);
08197       return RESULT_FAILURE;
08198    }
08199    AST_LIST_UNLOCK(&users);
08200    return RESULT_SUCCESS;
08201 }

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

Definition at line 8203 of file app_voicemail.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, vm_zone::list, vm_zone::msg_format, vm_zone::name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and vm_zone::timezone.

08204 {
08205    struct vm_zone *zone;
08206    char *output_format = "%-15s %-20s %-45s\n";
08207    int res = RESULT_SUCCESS;
08208 
08209    if (argc != 3)
08210       return RESULT_SHOWUSAGE;
08211 
08212    AST_LIST_LOCK(&zones);
08213    if (!AST_LIST_EMPTY(&zones)) {
08214       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
08215       AST_LIST_TRAVERSE(&zones, zone, list) {
08216          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
08217       }
08218    } else {
08219       ast_cli(fd, "There are no voicemail zones currently defined\n");
08220       res = RESULT_FAILURE;
08221    }
08222    AST_LIST_UNLOCK(&zones);
08223 
08224    return res;
08225 }

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

Definition at line 3912 of file app_voicemail.c.

References __has_voicemail(), and ast_copy_string().

03913 {
03914    char tmp[256], *tmp2 = tmp, *mbox, *context;
03915    ast_copy_string(tmp, mailbox, sizeof(tmp));
03916    while ((mbox = strsep(&tmp2, ","))) {
03917       if ((context = strchr(mbox, '@')))
03918          *context++ = '\0';
03919       else
03920          context = "default";
03921       if (__has_voicemail(context, mbox, folder, 1))
03922          return 1;
03923    }
03924    return 0;
03925 }

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

Definition at line 3928 of file app_voicemail.c.

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

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

03929 {
03930    char tmp[256];
03931    char *context;
03932 
03933    if (newmsgs)
03934       *newmsgs = 0;
03935    if (oldmsgs)
03936       *oldmsgs = 0;
03937    /* If no mailbox, return immediately */
03938    if (ast_strlen_zero(mailbox))
03939       return 0;
03940    if (strchr(mailbox, ',')) {
03941       int tmpnew, tmpold;
03942       char *mb, *cur;
03943 
03944       ast_copy_string(tmp, mailbox, sizeof(tmp));
03945       mb = tmp;
03946       while ((cur = strsep(&mb, ", "))) {
03947          if (!ast_strlen_zero(cur)) {
03948             if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
03949                return -1;
03950             else {
03951                if (newmsgs)
03952                   *newmsgs += tmpnew; 
03953                if (oldmsgs)
03954                   *oldmsgs += tmpold;
03955             }
03956          }
03957       }
03958       return 0;
03959    }
03960    ast_copy_string(tmp, mailbox, sizeof(tmp));
03961    context = strchr(tmp, '@');
03962    if (context) {
03963       *context = '\0';
03964       context++;
03965    } else
03966       context = "default";
03967    if (newmsgs)
03968       *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
03969    if (oldmsgs)
03970       *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
03971    return 0;
03972 }

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

Definition at line 2905 of file app_voicemail.c.

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

Referenced by inchar(), and sip_addheader().

02906 {
02907    int l;
02908 
02909    if (bio->ateof)
02910       return 0;
02911 
02912    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
02913       if (ferror(fi))
02914          return -1;
02915 
02916       bio->ateof = 1;
02917       return 0;
02918    }
02919 
02920    bio->iolen= l;
02921    bio->iocp= 0;
02922 
02923    return 1;
02924 }

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

Definition at line 2926 of file app_voicemail.c.

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

Referenced by base_encode().

02927 {
02928    if (bio->iocp>=bio->iolen) {
02929       if (!inbuf(bio, fi))
02930          return EOF;
02931    }
02932 
02933    return bio->iobuf[bio->iocp++];
02934 }

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

Definition at line 3639 of file app_voicemail.c.

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

Referenced by leave_voicemail().

03640 {
03641    int res;
03642    char fn[PATH_MAX];
03643    char dest[PATH_MAX];
03644 
03645    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, ext);
03646 
03647    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "greet"))) {
03648       ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
03649       return -1;
03650    }
03651 
03652    res = play_greeting(chan, vmu, fn, ecodes);
03653    if (res == -2) {
03654       /* File did not exist */
03655       res = ast_stream_and_wait(chan, "vm-theperson", chan->language, ecodes);
03656       if (res)
03657          return res;
03658       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
03659    }
03660 
03661    if (res)
03662       return res;
03663 
03664    res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language, ecodes);
03665    return res;
03666 }

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

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

02786 {
02787    int x;
02788    char fn[PATH_MAX];
02789 
02790    if (vm_lock_path(dir))
02791       return ERROR_LOCK_PATH;
02792 
02793    for (x = 0; x < vmu->maxmsg; x++) {
02794       make_file(fn, sizeof(fn), dir, x);
02795       if (ast_fileexists(fn, NULL, NULL) < 1)
02796          break;
02797    }
02798    ast_unlock_path(dir);
02799 
02800    return x - 1;
02801 }

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

Definition at line 4023 of file app_voicemail.c.

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

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

04024 {
04025 #ifdef IMAP_STORAGE
04026    int newmsgs, oldmsgs;
04027 #endif
04028    struct vm_state *vms = NULL;
04029    char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
04030    char callerid[256];
04031    FILE *txt;
04032    char date[50];
04033    int txtdes;
04034    int res = 0;
04035    int msgnum;
04036    int duration = 0;
04037    int ausemacro = 0;
04038    int ousemacro = 0;
04039    int ouseexten = 0;
04040    char dir[PATH_MAX], tmpdir[PATH_MAX];
04041    char dest[PATH_MAX];
04042    char fn[PATH_MAX];
04043    char prefile[PATH_MAX] = "";
04044    char tempfile[PATH_MAX] = "";
04045    char ext_context[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2] = "";
04046    char fmt[80];
04047    char *context;
04048    char ecodes[16] = "#";
04049    char tmp[1324] = "", *tmpptr;
04050    struct ast_vm_user *vmu;
04051    struct ast_vm_user svm;
04052    const char *category = NULL;
04053 
04054    if (strlen(ext) > sizeof(tmp) - 1) {
04055       ast_log(LOG_WARNING, "List of extensions is too long (>%ld).  Truncating.\n", (long) sizeof(tmp) - 1);
04056    }
04057    ast_copy_string(tmp, ext, sizeof(tmp));
04058    ext = tmp;
04059    context = strchr(tmp, '@');
04060    if (context) {
04061       *context++ = '\0';
04062       tmpptr = strchr(context, '&');
04063    } else {
04064       tmpptr = strchr(ext, '&');
04065    }
04066 
04067    if (tmpptr)
04068       *tmpptr++ = '\0';
04069 
04070    category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
04071 
04072    if (option_debug > 2)
04073       ast_log(LOG_DEBUG, "Before find_user\n");
04074    if (!(vmu = find_user(&svm, context, ext))) {
04075       ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
04076       if (ast_test_flag(options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
04077          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
04078       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04079       return res;
04080    }
04081    /* Setup pre-file if appropriate */
04082    if (strcmp(vmu->context, "default"))
04083       snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
04084    else
04085       ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
04086    if (ast_test_flag(options, OPT_BUSY_GREETING)) {
04087       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "busy");
04088       snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
04089    } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
04090       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "unavail");
04091       snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
04092    }
04093    snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
04094    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "temp"))) {
04095       ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
04096       return -1;
04097    }
04098    RETRIEVE(tempfile, -1, vmu);
04099    if (ast_fileexists(tempfile, NULL, NULL) > 0)
04100       ast_copy_string(prefile, tempfile, sizeof(prefile));
04101    DISPOSE(tempfile, -1);
04102    /* It's easier just to try to make it than to check for its existence */
04103    create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
04104    create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp");
04105 
04106    /* Check current or macro-calling context for special extensions */
04107    if (ast_test_flag(vmu, VM_OPERATOR)) {
04108       if (!ast_strlen_zero(vmu->exit)) {
04109          if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
04110             strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
04111             ouseexten = 1;
04112          }
04113       } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
04114          strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
04115          ouseexten = 1;
04116       }
04117       else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
04118       strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
04119       ousemacro = 1;
04120       }
04121    }
04122 
04123    if (!ast_strlen_zero(vmu->exit)) {
04124       if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
04125          strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
04126    } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
04127       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
04128    else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
04129       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
04130       ausemacro = 1;
04131    }
04132 
04133    /* Play the beginning intro if desired */
04134    if (!ast_strlen_zero(prefile)) {
04135       res = play_greeting(chan, vmu, prefile, ecodes);
04136       if (res == -2) {
04137          /* The file did not exist */
04138          if (option_debug)
04139             ast_log(LOG_DEBUG, "%s doesn't exist, doing what we can\n", prefile);
04140          res = invent_message(chan, vmu, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
04141       }
04142       if (res < 0) {
04143          if (option_debug)
04144             ast_log(LOG_DEBUG, "Hang up during prefile playback\n");
04145          free_user(vmu);
04146          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04147          return -1;
04148       }
04149    }
04150    if (res == '#') {
04151       /* On a '#' we skip the instructions */
04152       ast_set_flag(options, OPT_SILENT);
04153       res = 0;
04154    }
04155    if (!res && !ast_test_flag(options, OPT_SILENT)) {
04156       res = ast_stream_and_wait(chan, INTRO, chan->language, ecodes);
04157       if (res == '#') {
04158          ast_set_flag(options, OPT_SILENT);
04159          res = 0;
04160       }
04161    }
04162    if (res > 0)
04163       ast_stopstream(chan);
04164    /* Check for a '*' here in case the caller wants to escape from voicemail to something
04165     other than the operator -- an automated attendant or mailbox login for example */
04166    if (res == '*') {
04167       chan->exten[0] = 'a';
04168       chan->exten[1] = '\0';
04169       if (!ast_strlen_zero(vmu->exit)) {
04170          ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
04171       } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
04172          ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
04173       }
04174       chan->priority = 0;
04175       free_user(vmu);
04176       pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
04177       return 0;
04178    }
04179 
04180    /* Check for a '0' here */
04181    if (res == '0') {
04182    transfer:
04183       if (ouseexten || ousemacro) {
04184          chan->exten[0] = 'o';
04185          chan->exten[1] = '\0';
04186          if (!ast_strlen_zero(vmu->exit)) {
04187             ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
04188          } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
04189             ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
04190          }
04191          ast_play_and_wait(chan, "transfer");
04192          chan->priority = 0;
04193          free_user(vmu);
04194          pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
04195       }
04196       return 0;
04197    }
04198    if (res < 0) {
04199       free_user(vmu);
04200       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04201       return -1;
04202    }
04203    /* The meat of recording the message...  All the announcements and beeps have been played*/
04204    ast_copy_string(fmt, vmfmts, sizeof(fmt));
04205    if (!ast_strlen_zero(fmt)) {
04206       msgnum = 0;
04207 
04208 #ifdef IMAP_STORAGE
04209       /* Is ext a mailbox? */
04210       /* must open stream for this user to get info! */
04211       res = inboxcount(ext_context, &newmsgs, &oldmsgs);
04212       if (res < 0) {
04213          ast_log(LOG_NOTICE,"Can not leave voicemail, unable to count messages\n");
04214          return -1;
04215       }
04216       if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) {
04217       /*It is possible under certain circumstances that inboxcount did not create a vm_state when it was needed. This is a catchall which will
04218        * rarely be used*/
04219          if (!(vms = create_vm_state_from_user(vmu))) {
04220             ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
04221             return -1;
04222          }
04223       }
04224       vms->newmessages++;
04225       /* here is a big difference! We add one to it later */
04226       msgnum = newmsgs + oldmsgs;
04227       if (option_debug > 2)
04228          ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
04229       snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
04230       /* set variable for compatability */
04231       pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
04232 
04233       /* Check if mailbox is full */
04234       check_quota(vms, imapfolder);
04235       if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
04236          if (option_debug)
04237             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
04238          ast_play_and_wait(chan, "vm-mailboxfull");
04239          return -1;
04240       }
04241       if (option_debug > 2)
04242          ast_log(LOG_DEBUG, "Checking message number quota - mailbox has %d messages, maximum is set to %d\n",msgnum,vmu->maxmsg);
04243       if (msgnum >= vmu->maxmsg) {
04244          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
04245          if (!res)
04246             res = ast_waitstream(chan, "");
04247          ast_log(LOG_WARNING, "No more messages possible\n");
04248          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04249          goto leave_vm_out;
04250       }
04251 
04252       /* Check if we have exceeded maxmsg */
04253       if (msgnum >= vmu->maxmsg) {
04254          ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
04255          ast_play_and_wait(chan, "vm-mailboxfull");
04256          return -1;
04257       }
04258 #else
04259       if (count_messages(vmu, dir) >= vmu->maxmsg) {
04260          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
04261          if (!res)
04262             res = ast_waitstream(chan, "");
04263          ast_log(LOG_WARNING, "No more messages possible\n");
04264          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04265          goto leave_vm_out;
04266       }
04267 
04268 #endif
04269       snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
04270       txtdes = mkstemp(tmptxtfile);
04271       chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
04272       if (txtdes < 0) {
04273          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
04274          if (!res)
04275             res = ast_waitstream(chan, "");
04276          ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
04277          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04278          goto leave_vm_out;
04279       }
04280 
04281       /* Now play the beep once we have the message number for our next message. */
04282       if (res >= 0) {
04283          /* Unless we're *really* silent, try to send the beep */
04284          res = ast_stream_and_wait(chan, "beep", chan->language, "");
04285       }
04286             
04287       /* Store information */
04288       txt = fdopen(txtdes, "w+");
04289       if (txt) {
04290          get_date(date, sizeof(date));
04291          fprintf(txt, 
04292             ";\n"
04293             "; Message Information file\n"
04294             ";\n"
04295             "[message]\n"
04296             "origmailbox=%s\n"
04297             "context=%s\n"
04298             "macrocontext=%s\n"
04299             "exten=%s\n"
04300             "priority=%d\n"
04301             "callerchan=%s\n"
04302             "callerid=%s\n"
04303             "origdate=%s\n"
04304             "origtime=%ld\n"
04305             "category=%s\n",
04306             ext,
04307             chan->context,
04308             chan->macrocontext, 
04309             chan->exten,
04310             chan->priority,
04311             chan->name,
04312             ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
04313             date, (long)time(NULL),
04314             category ? category : ""); 
04315       } else
04316          ast_log(LOG_WARNING, "Error opening text file for output\n");
04317       res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, vms);
04318 
04319       if (txt) {
04320          if (duration < vmminmessage) {
04321             fclose(txt);
04322             if (option_verbose > 2) 
04323                ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage);
04324             ast_filedelete(tmptxtfile, NULL);
04325             unlink(tmptxtfile);
04326          } else {
04327             fprintf(txt, "duration=%d\n", duration);
04328             fclose(txt);
04329             if (vm_lock_path(dir)) {
04330                ast_log(LOG_ERROR, "Couldn't lock directory %s.  Voicemail will be lost.\n", dir);
04331                /* Delete files */
04332                ast_filedelete(tmptxtfile, NULL);
04333                unlink(tmptxtfile);
04334             } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
04335                if (option_debug) 
04336                   ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
04337                unlink(tmptxtfile);
04338                ast_unlock_path(dir);
04339             } else {
04340                for (;;) {
04341                   make_file(fn, sizeof(fn), dir, msgnum);
04342                   if (!EXISTS(dir, msgnum, fn, NULL))
04343                      break;
04344                   msgnum++;
04345                }
04346 
04347                /* assign a variable with the name of the voicemail file */ 
04348 #ifndef IMAP_STORAGE
04349                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
04350 #else
04351                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
04352 #endif
04353 
04354                snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
04355                ast_filerename(tmptxtfile, fn, NULL);
04356                rename(tmptxtfile, txtfile);
04357 
04358                ast_unlock_path(dir);
04359                /* We must store the file first, before copying the message, because
04360                 * ODBC storage does the entire copy with SQL.
04361                 */
04362                if (ast_fileexists(fn, NULL, NULL) > 0) {
04363                   STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms);
04364                }
04365 
04366                /* Are there to be more recipients of this message? */
04367                while (tmpptr) {
04368                   struct ast_vm_user recipu, *recip;
04369                   char *exten, *context;
04370                
04371                   exten = strsep(&tmpptr, "&");
04372                   context = strchr(exten, '@');
04373                   if (context) {
04374                      *context = '\0';
04375                      context++;
04376                   }
04377                   if ((recip = find_user(&recipu, context, exten))) {
04378                      copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir);
04379                      free_user(recip);
04380                   }
04381                }
04382                /* Notification and disposal needs to happen after the copy, though. */
04383                if (ast_fileexists(fn, NULL, NULL)) {
04384                   notify_new_message(chan, vmu, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
04385                   DISPOSE(dir, msgnum);
04386                }
04387             }
04388          }
04389       }
04390       if (res == '0') {
04391          goto transfer;
04392       } else if (res > 0)
04393          res = 0;
04394 
04395       if (duration < vmminmessage)
04396          /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
04397          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04398       else
04399          pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
04400    } else
04401       ast_log(LOG_WARNING, "No format for saving voicemail?\n");
04402 leave_vm_out:
04403    free_user(vmu);
04404    
04405    return res;
04406 }

static int load_config ( void   )  [static]

Definition at line 8290 of file app_voicemail.c.

References append_mailbox(), apply_options_full(), ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_config_option(), ast_copy_string(), ast_false(), ast_format_str_reduce(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_malloc, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, find_or_create(), free, free_vm_users(), globalflags, vm_zone::list, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, vm_zone::msg_format, option_debug, populate_defaults(), s, SENDMAIL, smdi_iface, vm_zone::timezone, var, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_OPERATOR, VM_PBXSKIP, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, and VOICEMAIL_CONFIG.

08291 {
08292    struct ast_vm_user *cur;
08293    struct ast_config *cfg, *ucfg;
08294    char *cat;
08295    struct ast_variable *var;
08296    const char *notifystr = NULL;
08297    const char *smdistr = NULL;
08298    const char *astattach;
08299    const char *astsearch;
08300    const char *astsaycid;
08301    const char *send_voicemail;
08302 #ifdef IMAP_STORAGE
08303    const char *imap_server;
08304    const char *imap_port;
08305    const char *imap_flags;
08306    const char *imap_folder;
08307    const char *auth_user;
08308    const char *auth_password;
08309    const char *expunge_on_hangup;
08310    const char *imap_timeout;
08311 #endif
08312    const char *astcallop;
08313    const char *astreview;
08314    const char *asttempgreetwarn;
08315    const char *astskipcmd;
08316    const char *asthearenv;
08317    const char *astsaydurationinfo;
08318    const char *astsaydurationminfo;
08319    const char *silencestr;
08320    const char *maxmsgstr;
08321    const char *astdirfwd;
08322    const char *thresholdstr;
08323    const char *fmt;
08324    const char *astemail;
08325    const char *ucontext;
08326    const char *astmailcmd = SENDMAIL;
08327    const char *astpreprocesscmd;
08328    const char *astpreprocessfmt;
08329    const char *astforcename;
08330    const char *astforcegreet;
08331    const char *s;
08332    char *q,*stringp, *tmp;
08333    const char *dialoutcxt = NULL;
08334    const char *callbackcxt = NULL;  
08335    const char *exitcxt = NULL;   
08336    const char *extpc;
08337    const char *emaildateformatstr;
08338    const char *volgainstr;
08339    int x;
08340    int tmpadsi[4];
08341 
08342    cfg = ast_config_load(VOICEMAIL_CONFIG);
08343 
08344    free_vm_users();
08345 
08346    AST_LIST_LOCK(&users);
08347 
08348    memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
08349 
08350    if (cfg) {
08351       /* General settings */
08352 
08353       if (!(ucontext = ast_variable_retrieve(cfg, "general", "userscontext")))
08354          ucontext = "default";
08355       ast_copy_string(userscontext, ucontext, sizeof(userscontext));
08356       /* Attach voice message to mail message ? */
08357       if (!(astattach = ast_variable_retrieve(cfg, "general", "attach"))) 
08358          astattach = "yes";
08359       ast_set2_flag((&globalflags), ast_true(astattach), VM_ATTACH); 
08360 
08361       if (!(astsearch = ast_variable_retrieve(cfg, "general", "searchcontexts")))
08362          astsearch = "no";
08363       ast_set2_flag((&globalflags), ast_true(astsearch), VM_SEARCH);
08364 
08365       volgain = 0.0;
08366       if ((volgainstr = ast_variable_retrieve(cfg, "general", "volgain")))
08367          sscanf(volgainstr, "%30lf", &volgain);
08368 
08369 #ifdef ODBC_STORAGE
08370       strcpy(odbc_database, "asterisk");
08371       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
08372          ast_copy_string(odbc_database, thresholdstr, sizeof(odbc_database));
08373       }
08374       strcpy(odbc_table, "voicemessages");
08375       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbctable"))) {
08376          ast_copy_string(odbc_table, thresholdstr, sizeof(odbc_table));
08377       }
08378 #endif      
08379       /* Mail command */
08380       strcpy(mailcmd, SENDMAIL);
08381       if ((astmailcmd = ast_variable_retrieve(cfg, "general", "mailcmd")))
08382          ast_copy_string(mailcmd, astmailcmd, sizeof(mailcmd)); /* User setting */
08383 
08384       if ((astpreprocesscmd = ast_variable_retrieve(cfg, "general", "preprocesscmd")))
08385          ast_copy_string(preprocesscmd, astpreprocesscmd, sizeof(preprocesscmd)); /* User setting */
08386 
08387       if ((astpreprocessfmt = ast_variable_retrieve(cfg, "general", "preprocessfmt")))
08388          ast_copy_string(preprocessfmt, astpreprocessfmt, sizeof(preprocessfmt)); /* User setting */
08389 
08390       maxsilence = 0;
08391       if ((silencestr = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
08392          maxsilence = atoi(silencestr);
08393          if (maxsilence > 0)
08394             maxsilence *= 1000;
08395       }
08396       
08397       if (!(maxmsgstr = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
08398          maxmsg = MAXMSG;
08399       } else {
08400          maxmsg = atoi(maxmsgstr);
08401          if (maxmsg <= 0) {
08402             ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", maxmsgstr, MAXMSG);
08403             maxmsg = MAXMSG;
08404          } else if (maxmsg > MAXMSGLIMIT) {
08405             ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, maxmsgstr);
08406             maxmsg = MAXMSGLIMIT;
08407          }
08408       }
08409 
08410       /* Load date format config for voicemail mail */
08411       if ((emaildateformatstr = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
08412          ast_copy_string(emaildateformat, emaildateformatstr, sizeof(emaildateformat));
08413       }
08414 
08415       /* External password changing command */
08416       if ((extpc = ast_variable_retrieve(cfg, "general", "externpass"))) {
08417          ast_copy_string(ext_pass_cmd,extpc,sizeof(ext_pass_cmd));
08418       }
08419 #ifdef IMAP_STORAGE
08420       /* IMAP server address */
08421       if ((imap_server = ast_variable_retrieve(cfg, "general", "imapserver"))) {
08422          ast_copy_string(imapserver, imap_server, sizeof(imapserver));
08423       } else {
08424          ast_copy_string(imapserver,"localhost", sizeof(imapserver));
08425       }
08426       /* IMAP server port */
08427       if ((imap_port = ast_variable_retrieve(cfg, "general", "imapport"))) {
08428          ast_copy_string(imapport, imap_port, sizeof(imapport));
08429       } else {
08430          ast_copy_string(imapport,"143", sizeof(imapport));
08431       }
08432       /* IMAP server flags */
08433       if ((imap_flags = ast_variable_retrieve(cfg, "general", "imapflags"))) {
08434          ast_copy_string(imapflags, imap_flags, sizeof(imapflags));
08435       }
08436       /* IMAP server master username */
08437       if ((auth_user = ast_variable_retrieve(cfg, "general", "authuser"))) {
08438          ast_copy_string(authuser, auth_user, sizeof(authuser));
08439       }
08440       /* IMAP server master password */
08441       if ((auth_password = ast_variable_retrieve(cfg, "general", "authpassword"))) {
08442          ast_copy_string(authpassword, auth_password, sizeof(authpassword));
08443       }
08444       /* Expunge on exit */
08445       if ((expunge_on_hangup = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) {
08446          if (ast_false(expunge_on_hangup))
08447             expungeonhangup = 0;
08448          else
08449             expungeonhangup = 1;
08450       } else {
08451          expungeonhangup = 1;
08452       }
08453       /* IMAP voicemail folder */
08454       if ((imap_folder = ast_variable_retrieve(cfg, "general", "imapfolder"))) {
08455          ast_copy_string(imapfolder, imap_folder, sizeof(imapfolder));
08456       } else {
08457          ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
08458       }
08459 
08460       /* There is some very unorthodox casting done here. This is due
08461        * to the way c-client handles the argument passed in. It expects a 
08462        * void pointer and casts the pointer directly to a long without
08463        * first dereferencing it. */
08464 
08465       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) {
08466          mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(imap_timeout)));
08467       } else {
08468          mail_parameters(NIL, SET_READTIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08469       }
08470 
08471       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) {
08472          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(imap_timeout)));
08473       } else {
08474          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08475       }
08476 
08477       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) {
08478          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(imap_timeout)));
08479       } else {
08480          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08481       }
08482 
08483       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) {
08484          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(imap_timeout)));
08485       } else {
08486          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08487       }
08488 
08489       /* Increment configuration version */
08490       imapversion++;
08491 #endif
08492       /* External voicemail notify application */
08493       
08494       if ((notifystr = ast_variable_retrieve(cfg, "general", "externnotify"))) {
08495          ast_copy_string(externnotify, notifystr, sizeof(externnotify));
08496          if (option_debug > 2)
08497             ast_log(LOG_DEBUG, "found externnotify: %s\n", externnotify);
08498          if (!strcasecmp(externnotify, "smdi")) {
08499             if (option_debug)
08500                ast_log(LOG_DEBUG, "Using SMDI for external voicemail notification\n");
08501             if ((smdistr = ast_variable_retrieve(cfg, "general", "smdiport"))) {
08502                smdi_iface = ast_smdi_interface_find(smdistr);
08503             } else {
08504                if (option_debug)
08505                   ast_log(LOG_DEBUG, "No SMDI interface set, trying default (/dev/ttyS0)\n");
08506                smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
08507             }
08508 
08509             if (!smdi_iface) {
08510                ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling external voicemail notification\n");
08511                externnotify[0] = '\0';
08512             }
08513          }
08514       } else {
08515          externnotify[0] = '\0';
08516       }
08517 
08518       /* Silence treshold */
08519       silencethreshold = 256;
08520       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "silencethreshold")))
08521          silencethreshold = atoi(thresholdstr);
08522       
08523       if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail"))) 
08524          astemail = ASTERISK_USERNAME;
08525       ast_copy_string(serveremail, astemail, sizeof(serveremail));
08526       
08527       vmmaxmessage = 0;
08528       if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
08529          if (sscanf(s, "%30d", &x) == 1) {
08530             vmmaxmessage = x;
08531          } else {
08532             ast_log(LOG_WARNING, "Invalid max message time length\n");
08533          }
08534       }
08535 
08536       vmminmessage = 0;
08537       if ((s = ast_variable_retrieve(cfg, "general", "minmessage"))) {
08538          if (sscanf(s, "%30d", &x) == 1) {
08539             vmminmessage = x;
08540             if (maxsilence / 1000 >= vmminmessage)
08541                ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
08542          } else {
08543             ast_log(LOG_WARNING, "Invalid min message time length\n");
08544          }
08545       }
08546       fmt = ast_variable_retrieve(cfg, "general", "format");
08547       if (!fmt) {
08548          fmt = "wav";   
08549       } else {
08550          tmp = ast_strdupa(fmt);
08551          fmt = ast_format_str_reduce(tmp);
08552          if (!fmt) {
08553             ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n");
08554             fmt = "wav";
08555          }
08556       }
08557 
08558       ast_copy_string(vmfmts, fmt, sizeof(vmfmts));
08559 
08560       skipms = 3000;
08561       if ((s = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
08562          if (sscanf(s, "%30d", &x) == 1) {
08563             maxgreet = x;
08564          } else {
08565             ast_log(LOG_WARNING, "Invalid max message greeting length\n");
08566          }
08567       }
08568 
08569       if ((s = ast_variable_retrieve(cfg, "general", "skipms"))) {
08570          if (sscanf(s, "%30d", &x) == 1) {
08571             skipms = x;
08572          } else {
08573             ast_log(LOG_WARNING, "Invalid skipms value\n");
08574          }
08575       }
08576 
08577       maxlogins = 3;
08578       if ((s = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
08579          if (sscanf(s, "%30d", &x) == 1) {
08580             maxlogins = x;
08581          } else {
08582             ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
08583          }
08584       }
08585 
08586       /* Force new user to record name ? */
08587       if (!(astforcename = ast_variable_retrieve(cfg, "general", "forcename"))) 
08588          astforcename = "no";
08589       ast_set2_flag((&globalflags), ast_true(astforcename), VM_FORCENAME);
08590 
08591       /* Force new user to record greetings ? */
08592       if (!(astforcegreet = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 
08593          astforcegreet = "no";
08594       ast_set2_flag((&globalflags), ast_true(astforcegreet), VM_FORCEGREET);
08595 
08596       if ((s = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))){
08597          if (option_debug > 2)
08598             ast_log(LOG_DEBUG,"VM_CID Internal context string: %s\n",s);
08599          stringp = ast_strdupa(s);
08600          for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
08601             if (!ast_strlen_zero(stringp)) {
08602                q = strsep(&stringp,",");
08603                while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
08604                   q++;
08605                ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
08606                if (option_debug > 2)
08607                   ast_log(LOG_DEBUG,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
08608             } else {
08609                cidinternalcontexts[x][0] = '\0';
08610             }
08611          }
08612       }
08613       if (!(astreview = ast_variable_retrieve(cfg, "general", "review"))){
08614          if (option_debug)
08615             ast_log(LOG_DEBUG,"VM Review Option disabled globally\n");
08616          astreview = "no";
08617       }
08618       ast_set2_flag((&globalflags), ast_true(astreview), VM_REVIEW); 
08619 
08620       /*Temperary greeting reminder */
08621       if (!(asttempgreetwarn = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) {
08622          if (option_debug)
08623             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option disabled globally\n");
08624          asttempgreetwarn = "no";
08625       } else {
08626          if (option_debug)
08627             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option enabled globally\n");
08628       }
08629       ast_set2_flag((&globalflags), ast_true(asttempgreetwarn), VM_TEMPGREETWARN);
08630 
08631       if (!(astcallop = ast_variable_retrieve(cfg, "general", "operator"))){
08632          if (option_debug)
08633             ast_log(LOG_DEBUG,"VM Operator break disabled globally\n");
08634          astcallop = "no";
08635       }
08636       ast_set2_flag((&globalflags), ast_true(astcallop), VM_OPERATOR);  
08637 
08638       if (!(astsaycid = ast_variable_retrieve(cfg, "general", "saycid"))) {
08639          if (option_debug)
08640             ast_log(LOG_DEBUG,"VM CID Info before msg disabled globally\n");
08641          astsaycid = "no";
08642       } 
08643       ast_set2_flag((&globalflags), ast_true(astsaycid), VM_SAYCID); 
08644 
08645       if (!(send_voicemail = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){
08646          if (option_debug)
08647             ast_log(LOG_DEBUG,"Send Voicemail msg disabled globally\n");
08648          send_voicemail = "no";
08649       }
08650       ast_set2_flag((&globalflags), ast_true(send_voicemail), VM_SVMAIL);
08651    
08652       if (!(asthearenv = ast_variable_retrieve(cfg, "general", "envelope"))) {
08653          if (option_debug)
08654             ast_log(LOG_DEBUG,"ENVELOPE before msg enabled globally\n");
08655          asthearenv = "yes";
08656       }
08657       ast_set2_flag((&globalflags), ast_true(asthearenv), VM_ENVELOPE); 
08658 
08659       if (!(astsaydurationinfo = ast_variable_retrieve(cfg, "general", "sayduration"))) {
08660          if (option_debug)
08661             ast_log(LOG_DEBUG,"Duration info before msg enabled globally\n");
08662          astsaydurationinfo = "yes";
08663       }
08664       ast_set2_flag((&globalflags), ast_true(astsaydurationinfo), VM_SAYDURATION);  
08665 
08666       saydurationminfo = 2;
08667       if ((astsaydurationminfo = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
08668          if (sscanf(astsaydurationminfo, "%30d", &x) == 1) {
08669             saydurationminfo = x;
08670          } else {
08671             ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
08672          }
08673       }
08674 
08675       if (!(astskipcmd = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
08676          if (option_debug)
08677             ast_log(LOG_DEBUG,"We are not going to skip to the next msg after save/delete\n");
08678          astskipcmd = "no";
08679       }
08680       ast_set2_flag((&globalflags), ast_true(astskipcmd), VM_SKIPAFTERCMD);
08681 
08682       if ((dialoutcxt = ast_variable_retrieve(cfg, "general", "dialout"))) {
08683          ast_copy_string(dialcontext, dialoutcxt, sizeof(dialcontext));
08684          if (option_debug)
08685             ast_log(LOG_DEBUG, "found dialout context: %s\n", dialcontext);
08686       } else {
08687          dialcontext[0] = '\0';  
08688       }
08689       
08690       if ((callbackcxt = ast_variable_retrieve(cfg, "general", "callback"))) {
08691          ast_copy_string(callcontext, callbackcxt, sizeof(callcontext));
08692          if (option_debug)
08693             ast_log(LOG_DEBUG, "found callback context: %s\n", callcontext);
08694       } else {
08695          callcontext[0] = '\0';
08696       }
08697 
08698       if ((exitcxt = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
08699          ast_copy_string(exitcontext, exitcxt, sizeof(exitcontext));
08700          if (option_debug)
08701             ast_log(LOG_DEBUG, "found operator context: %s\n", exitcontext);
08702       } else {
08703          exitcontext[0] = '\0';
08704       }
08705 
08706       if (!(astdirfwd = ast_variable_retrieve(cfg, "general", "usedirectory"))) 
08707          astdirfwd = "no";
08708       ast_set2_flag((&globalflags), ast_true(astdirfwd), VM_DIRECFORWARD); 
08709       if ((ucfg = ast_config_load("users.conf"))) {   
08710          for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
08711             if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
08712                continue;
08713             if ((cur = find_or_create(userscontext, cat))) {
08714                populate_defaults(cur);
08715                apply_options_full(cur, ast_variable_browse(ucfg, cat));
08716                ast_copy_string(cur->context, userscontext, sizeof(cur->context));
08717             }
08718          }
08719          ast_config_destroy(ucfg);
08720       }
08721       cat = ast_category_browse(cfg, NULL);
08722       while (cat) {
08723          if (strcasecmp(cat, "general")) {
08724             var = ast_variable_browse(cfg, cat);
08725             if (strcasecmp(cat, "zonemessages")) {
08726                /* Process mailboxes in this context */
08727                while (var) {
08728                   append_mailbox(cat, var->name, var->value);
08729                   var = var->next;
08730                }
08731             } else {
08732                /* Timezones in this context */
08733                while (var) {
08734                   struct vm_zone *z;
08735                   if ((z = ast_malloc(sizeof(*z)))) {
08736                      char *msg_format, *timezone;
08737                      msg_format = ast_strdupa(var->value);
08738                      timezone = strsep(&msg_format, "|");
08739                      if (msg_format) {
08740                         ast_copy_string(z->name, var->name, sizeof(z->name));
08741                         ast_copy_string(z->timezone, timezone, sizeof(z->timezone));
08742                         ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
08743                         AST_LIST_LOCK(&zones);
08744                         AST_LIST_INSERT_HEAD(&zones, z, list);
08745                         AST_LIST_UNLOCK(&zones);
08746                      } else {
08747                         ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
08748                         free(z);
08749                      }
08750                   } else {
08751                      free(z);
08752                      AST_LIST_UNLOCK(&users);
08753                      ast_config_destroy(cfg);
08754                      return -1;
08755                   }
08756                   var = var->next;
08757                }
08758             }
08759          }
08760          cat = ast_category_browse(cfg, cat);
08761       }
08762       memset(fromstring,0,sizeof(fromstring));
08763       memset(pagerfromstring,0,sizeof(pagerfromstring));
08764       memset(emailtitle,0,sizeof(emailtitle));
08765       strcpy(charset, "ISO-8859-1");
08766       if (emailbody) {
08767          free(emailbody);
08768          emailbody = NULL;
08769       }
08770       if (emailsubject) {
08771          free(emailsubject);
08772          emailsubject = NULL;
08773       }
08774       if (pagerbody) {
08775          free(pagerbody);
08776          pagerbody = NULL;
08777       }
08778       if (pagersubject) {
08779          free(pagersubject);
08780          pagersubject = NULL;
08781       }
08782       if ((s = ast_variable_retrieve(cfg, "general", "pbxskip")))
08783          ast_set2_flag((&globalflags), ast_true(s), VM_PBXSKIP);
08784       if ((s = ast_variable_retrieve(cfg, "general", "fromstring")))
08785          ast_copy_string(fromstring,s,sizeof(fromstring));
08786       if ((s = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
08787          ast_copy_string(pagerfromstring,s,sizeof(pagerfromstring));
08788       if ((s = ast_variable_retrieve(cfg, "general", "charset")))
08789          ast_copy_string(charset,s,sizeof(charset));
08790       if ((s = ast_variable_retrieve(cfg, "general", "adsifdn"))) {
08791          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
08792          for (x = 0; x < 4; x++) {
08793             memcpy(&adsifdn[x], &tmpadsi[x], 1);
08794          }
08795       }
08796       if ((s = ast_variable_retrieve(cfg, "general", "adsisec"))) {
08797          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
08798          for (x = 0; x < 4; x++) {
08799             memcpy(&adsisec[x], &tmpadsi[x], 1);
08800          }
08801       }
08802       if ((s = ast_variable_retrieve(cfg, "general", "adsiver")))
08803          if (atoi(s)) {
08804             adsiver = atoi(s);
08805          }
08806       if ((s = ast_variable_retrieve(cfg, "general", "emailtitle"))) {
08807          ast_log(LOG_NOTICE, "Keyword 'emailtitle' is DEPRECATED, please use 'emailsubject' instead.\n");
08808          ast_copy_string(emailtitle,s,sizeof(emailtitle));
08809       }
08810       if ((s = ast_variable_retrieve(cfg, "general", "emailsubject")))
08811          emailsubject = ast_strdup(s);
08812       if ((s = ast_variable_retrieve(cfg, "general", "emailbody"))) {
08813          char *tmpread, *tmpwrite;
08814          emailbody = ast_strdup(s);
08815 
08816          /* substitute strings \t and \n into the appropriate characters */
08817          tmpread = tmpwrite = emailbody;
08818          while ((tmpwrite = strchr(tmpread,'\\'))) {
08819             switch (tmpwrite[1]) {
08820             case 'r':
08821                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08822                *tmpwrite = '\r';
08823                break;
08824             case 'n':
08825                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08826                *tmpwrite = '\n';
08827                break;
08828             case 't':
08829                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08830                *tmpwrite = '\t';
08831                break;
08832             default:
08833                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
08834             }
08835             tmpread = tmpwrite + 1;
08836          }
08837       }
08838       if ((s = ast_variable_retrieve(cfg, "general", "tz"))) {
08839          ast_copy_string(zonetag, s, sizeof(zonetag));
08840       }
08841       if ((s = ast_variable_retrieve(cfg, "general", "pagersubject")))
08842          pagersubject = ast_strdup(s);
08843       if ((s = ast_variable_retrieve(cfg, "general", "pagerbody"))) {
08844          char *tmpread, *tmpwrite;
08845          pagerbody = ast_strdup(s);
08846 
08847          /* substitute strings \t and \n into the appropriate characters */
08848          tmpread = tmpwrite = pagerbody;
08849          while ((tmpwrite = strchr(tmpread, '\\'))) {
08850             switch (tmpwrite[1]) {
08851             case 'r':
08852                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08853                *tmpwrite = '\r';
08854                break;
08855             case 'n':
08856                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08857                *tmpwrite = '\n';
08858                break;
08859             case 't':
08860                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08861                *tmpwrite = '\t';
08862                break;
08863             default:
08864                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
08865             }
08866             tmpread = tmpwrite + 1;
08867          }
08868       }
08869       AST_LIST_UNLOCK(&users);
08870       ast_config_destroy(cfg);
08871       return 0;
08872    } else {
08873       AST_LIST_UNLOCK(&users);
08874       ast_log(LOG_WARNING, "Failed to load configuration file.\n");
08875       return 0;
08876    }
08877 }

static int load_module ( void   )  [static]

Definition at line 8900 of file app_voicemail.c.

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

08901 {
08902    int res;
08903    char *adsi_loaded = ast_module_helper("", "res_adsi", 0, 0, 0, 0);
08904    char *smdi_loaded = ast_module_helper("", "res_smdi", 0, 0, 0, 0);
08905    free(adsi_loaded);
08906    free(smdi_loaded);
08907 
08908    if (!adsi_loaded) {
08909       ast_log(LOG_ERROR, "app_voicemail.so depends upon res_adsi.so\n");
08910       return AST_MODULE_LOAD_DECLINE;
08911    }
08912 
08913    if (!smdi_loaded) {
08914       ast_log(LOG_ERROR, "app_voicemail.so depends upon res_smdi.so\n");
08915       return AST_MODULE_LOAD_DECLINE;
08916    }
08917 
08918    my_umask = umask(0);
08919    umask(my_umask);
08920    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
08921    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
08922    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
08923    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
08924    if (res)
08925       return(res);
08926 
08927    if ((res=load_config())) {
08928       return(res);
08929    }
08930 
08931    ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08932 
08933    /* compute the location of the voicemail spool directory */
08934    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
08935 
08936    ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
08937 
08938    return res;
08939 }

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

Definition at line 934 of file app_voicemail.c.

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

00935 {
00936    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
00937 }

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

Definition at line 3181 of file app_voicemail.c.

References ast_channel_alloc(), ast_channel_free(), ast_config_destroy(), ast_config_load(), ast_copy_string(), ast_localtime(), ast_log(), ast_random(), ast_safe_system(), AST_STATE_DOWN, ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), base_encode(), check_mime(), ast_vm_user::context, create_dirpath(), ast_vm_user::email, encode_mime_str(), ENDL, ast_vm_user::fullname, globalflags, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), ast_channel::name, option_debug, pbx_substitute_variables_helper(), prep_email_sub_vars(), ast_vm_user::preprocesscmd, ast_vm_user::preprocessfmt, ast_channel::priority, quote(), strip_control_and_high(), VM_PBXSKIP, vmu_tm(), VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.

Referenced by sendmail().

03182 {
03183    char date[256];
03184    char host[MAXHOSTNAMELEN] = "";
03185    char who[256];
03186    char bound[256];
03187    char fname[256];
03188    char dur[256];
03189    char enc_cidnum[256] = "", enc_cidname[256] = "";
03190    struct tm tm;
03191    char *passdata = NULL, *passdata2;
03192    size_t len_passdata = 0, len_passdata2, tmplen;
03193 #ifdef IMAP_STORAGE
03194 #define ENDL "\r\n"
03195 #else
03196 #define ENDL "\n"
03197 #endif
03198 
03199    /* One alloca for multiple fields */
03200    len_passdata2 = strlen(vmu->fullname);
03201    if (emailsubject && (tmplen = strlen(emailsubject)) > len_passdata2) {
03202       len_passdata2 = tmplen;
03203    }
03204    if ((tmplen = strlen(emailtitle)) > len_passdata2) {
03205       len_passdata2 = tmplen;
03206    }
03207    if ((tmplen = strlen(fromstring)) > len_passdata2) {
03208       len_passdata2 = tmplen;
03209    }
03210    len_passdata2 = len_passdata2 * 3 + 200;
03211    passdata2 = alloca(len_passdata2);
03212 
03213    if (cidnum) {
03214       strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum));
03215    }
03216    if (cidname) {
03217       strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname));
03218    }
03219    gethostname(host, sizeof(host) - 1);
03220    if (strchr(srcemail, '@'))
03221       ast_copy_string(who, srcemail, sizeof(who));
03222    else {
03223       snprintf(who, sizeof(who), "%s@%s", srcemail, host);
03224    }
03225    snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
03226    strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
03227    fprintf(p, "Date: %s" ENDL, date);
03228 
03229    /* Set date format for voicemail mail */
03230    strftime(date, sizeof(date), emaildateformat, &tm);
03231 
03232    if (*fromstring) {
03233       struct ast_channel *ast;
03234       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03235          char *ptr;
03236          memset(passdata2, 0, len_passdata2);
03237          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, passdata2, len_passdata2, category);
03238          pbx_substitute_variables_helper(ast, fromstring, passdata2, len_passdata2);
03239          len_passdata = strlen(passdata2) * 3 + 300;
03240          passdata = alloca(len_passdata);
03241          if (check_mime(passdata2)) {
03242             int first_line = 1;
03243             encode_mime_str(passdata2, passdata, len_passdata, strlen("From: "), strlen(who) + 3);
03244             while ((ptr = strchr(passdata, ' '))) {
03245                *ptr = '\0';
03246                fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", passdata);
03247                first_line = 0;
03248                passdata = ptr + 1;
03249             }
03250             fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", passdata, who);
03251          } else {
03252             fprintf(p, "From: %s <%s>" ENDL, quote(passdata2, passdata, len_passdata), who);
03253          }
03254          ast_channel_free(ast);
03255       } else
03256          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03257    } else
03258       fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
03259 
03260    if (check_mime(vmu->fullname)) {
03261       int first_line = 1;
03262       char *ptr;
03263       encode_mime_str(vmu->fullname, passdata2, len_passdata2, strlen("To: "), strlen(vmu->email) + 3);
03264       while ((ptr = strchr(passdata2, ' '))) {
03265          *ptr = '\0';
03266          fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", passdata2);
03267          first_line = 0;
03268          passdata2 = ptr + 1;
03269       }
03270       fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", passdata2, vmu->email);
03271    } else {
03272       fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata2), vmu->email);
03273    }
03274    if (emailsubject) {
03275       struct ast_channel *ast;
03276       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03277          int vmlen = strlen(emailsubject) * 3 + 200;
03278          /* Only allocate more space if the previous was not large enough */
03279          if (vmlen > len_passdata) {
03280             passdata = alloca(vmlen);
03281             len_passdata = vmlen;
03282          }
03283 
03284          memset(passdata, 0, len_passdata);
03285          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, len_passdata, category);
03286          pbx_substitute_variables_helper(ast, emailsubject, passdata, len_passdata);
03287          if (check_mime(passdata)) {
03288             int first_line = 1;
03289             char *ptr;
03290             encode_mime_str(passdata, passdata2, len_passdata2, strlen("Subject: "), 0);
03291             while ((ptr = strchr(passdata2, ' '))) {
03292                *ptr = '\0';
03293                fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2);
03294                first_line = 0;
03295                passdata2 = ptr + 1;
03296             }
03297             fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2);
03298          } else {
03299             fprintf(p, "Subject: %s" ENDL, passdata);
03300          }
03301          ast_channel_free(ast);
03302       } else {
03303          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03304       }
03305    } else   if (*emailtitle) {
03306       fprintf(p, emailtitle, msgnum + 1, mailbox) ;
03307       fprintf(p, ENDL) ;
03308    } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) {
03309       fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
03310    } else {
03311       fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
03312    }
03313    fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host);
03314    if (imap) {
03315       /* additional information needed for IMAP searching */
03316       fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
03317       /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */
03318       fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring);
03319       fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context);
03320 #ifdef IMAP_STORAGE
03321       fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox));
03322 #else
03323       fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
03324 #endif
03325       fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority);
03326       fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name);
03327       fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum);
03328       fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname);
03329       fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
03330       if (!ast_strlen_zero(category)) {
03331          fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category);
03332       }
03333       fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date);
03334       fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL));
03335    }
03336    if (!ast_strlen_zero(cidnum)) {
03337       fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum);
03338    }
03339    if (!ast_strlen_zero(cidname)) {
03340       fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname);
03341    }
03342    fprintf(p, "MIME-Version: 1.0" ENDL);
03343    if (attach_user_voicemail) {
03344       /* Something unique. */
03345       snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random());
03346 
03347       fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
03348       fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
03349       fprintf(p, "--%s" ENDL, bound);
03350    }
03351    fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
03352    if (emailbody) {
03353       struct ast_channel *ast;
03354       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03355          char *passdata;
03356          int vmlen = strlen(emailbody)*3 + 200;
03357          if ((passdata = alloca(vmlen))) {
03358             memset(passdata, 0, vmlen);
03359             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03360             pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen);
03361             fprintf(p, "%s" ENDL, passdata);
03362          } else
03363             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03364          ast_channel_free(ast);
03365       } else
03366          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03367    } else {
03368       if (strcmp(vmu->mailbox, mailbox)) {
03369          /* Forwarded type */
03370          struct ast_config *msg_cfg;
03371          const char *v;
03372          int inttime;
03373          char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = "";
03374          /* Retrieve info from VM attribute file */
03375          make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
03376          make_file(fromfile, sizeof(fromfile), fromdir, msgnum);
03377          if (strlen(fromfile) < sizeof(fromfile) - 5) {
03378             strcat(fromfile, ".txt");
03379          }
03380          if ((msg_cfg = ast_config_load(fromfile))) {
03381             if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
03382                ast_copy_string(origcallerid, v, sizeof(origcallerid));
03383             }
03384 
03385             /* You might be tempted to do origdate, except that a) it's in the wrong
03386              * format, and b) it's missing for IMAP recordings. */
03387             if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) {
03388                time_t ttime = inttime;
03389                struct tm tm;
03390                ast_localtime(&ttime, &tm, NULL);
03391                strftime(origdate, sizeof(origdate), emaildateformat, &tm);
03392             }
03393             fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded"
03394                " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL
03395                "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a"
03396                " chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur,
03397                msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")),
03398                date, origcallerid, origdate);
03399             ast_config_destroy(msg_cfg);
03400          } else {
03401             goto plain_message;
03402          }
03403       } else {
03404 plain_message:
03405          fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a "
03406             "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL
03407             "want to check it when you get a chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk"
03408             ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox,
03409             (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
03410       }
03411    }
03412    if (attach_user_voicemail) {
03413       char tmpdir[256], newtmp[256], tmpcmd[256], newfname[256];
03414       char newfmt[10];
03415       int tmpfd = -1;
03416       int exitstatus = 0;
03417 
03418       if (!ast_strlen_zero(vmu->preprocesscmd) || !ast_strlen_zero(preprocesscmd)) {
03419          create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
03420          snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
03421          tmpfd = mkstemp(newtmp);
03422          chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
03423          if (tmpfd > -1) {
03424             snprintf(newfmt, sizeof(newfmt), (!ast_strlen_zero(vmu->preprocesscmd)) ? (vmu->preprocessfmt ? vmu->preprocessfmt : format) : (preprocessfmt ? preprocessfmt : format));
03425             snprintf(newfname, sizeof(newfname), "%s.%s", newtmp, newfmt);
03426             snprintf(tmpcmd, sizeof(tmpcmd), "%s < %s.%s > %s", !ast_strlen_zero(vmu->preprocesscmd) ? vmu->preprocesscmd : preprocesscmd, attach, format, newfname);
03427             exitstatus = ast_safe_system(tmpcmd);
03428             if (option_debug)
03429                ast_log(LOG_DEBUG, "Executed preprocesscmd '%s', exitstatus %i\n", tmpcmd, exitstatus);
03430             if (exitstatus) {
03431                ast_log(LOG_WARNING, "Command %s exited with exitstatus %i\n", tmpcmd, exitstatus);
03432                close(tmpfd);
03433                unlink(fname);
03434             } else {
03435                attach = newtmp;
03436                strncpy(format, newfmt, 5);
03437                close(tmpfd);
03438             }
03439 
03440          }
03441       }
03442 
03443       /* Eww. We want formats to tell us their own MIME type */
03444       char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
03445    
03446       if (vmu->volgain < -.001 || vmu->volgain > .001) {
03447          create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
03448          snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
03449          tmpfd = mkstemp(newtmp);
03450          chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
03451          if (option_debug > 2)
03452             ast_log(LOG_DEBUG, "newtmp: %s\n", newtmp);
03453          if (tmpfd > -1) {
03454             int soxstatus;
03455             snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
03456             if ((soxstatus = ast_safe_system(tmpcmd)) == 0) {
03457                attach = newtmp;
03458                if (option_debug > 2) {
03459                   ast_log(LOG_DEBUG, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
03460                }
03461             } else {
03462                ast_log(LOG_WARNING, "Sox failed to reencode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format,
03463                   soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing");
03464                ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n");
03465             }
03466          }
03467       }
03468       fprintf(p, "--%s" ENDL, bound);
03469       if (strcasecmp(format, "mp3"))
03470          fprintf(p, "Content-Type: %s%s; name=\"msg%04d.%s\"" ENDL, ctype, format, msgnum + 1, format);
03471       else
03472          fprintf(p, "Content-Type: audio/mpeg; name=\"msg%04d.%s\"" ENDL, msgnum + 1, format);
03473       fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
03474       fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
03475       fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"" ENDL ENDL, msgnum + 1, format);
03476       snprintf(fname, sizeof(fname), "%s.%s", attach, format);
03477       base_encode(fname, p);
03478       fprintf(p, ENDL "--%s--" ENDL "." ENDL, bound);
03479       if (tmpfd > -1) {
03480          unlink(fname);
03481          close(tmpfd);
03482          unlink(newtmp);
03483       }
03484    }
03485 #undef ENDL
03486 }

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

Definition at line 939 of file app_voicemail.c.

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

00940 {
00941    return snprintf(dest, len, "%s/msg%04d", dir, num);
00942 }

static char* mbox ( int  id  )  [static]

Definition at line 996 of file app_voicemail.c.

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

00997 {
00998    static char *msgs[] = {
00999       "INBOX",
01000       "Old",
01001       "Work",
01002       "Family",
01003       "Friends",
01004       "Cust1",
01005       "Cust2",
01006       "Cust3",
01007       "Cust4",
01008       "Cust5",
01009    };
01010    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "tmp";
01011 }

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

Definition at line 3875 of file app_voicemail.c.

References __has_voicemail().

Referenced by load_module().

03876 {
03877    return __has_voicemail(context, mailbox, folder, 0);
03878 }

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

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

Referenced by copy_message(), and leave_voicemail().

05140 {
05141    char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
05142    int newmsgs = 0, oldmsgs = 0;
05143    const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
05144 
05145    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
05146    make_file(fn, sizeof(fn), todir, msgnum);
05147    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
05148 
05149    if (!ast_strlen_zero(vmu->attachfmt)) {
05150       if (strstr(fmt, vmu->attachfmt)) {
05151          fmt = vmu->attachfmt;
05152       } else {
05153          ast_log(LOG_WARNING, "Attachment format '%s' is not one of the recorded formats '%s'.  Falling back to default format for '%s@%s'.\n", vmu->attachfmt, fmt, vmu->mailbox, vmu->context);
05154       }
05155    }
05156 
05157    /* Attach only the first format */
05158    fmt = ast_strdupa(fmt);
05159    stringp = fmt;
05160    strsep(&stringp, "|");
05161 
05162    if (!ast_strlen_zero(vmu->email)) {
05163       int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
05164       char *myserveremail = serveremail;
05165       attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
05166       if (!ast_strlen_zero(vmu->serveremail))
05167          myserveremail = vmu->serveremail;
05168       
05169       if (attach_user_voicemail)
05170          RETRIEVE(todir, msgnum, vmu);
05171 
05172       /*XXX possible imap issue, should category be NULL XXX*/
05173       sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
05174 
05175       if (attach_user_voicemail)
05176          DISPOSE(todir, msgnum);
05177    }
05178 
05179    if (!ast_strlen_zero(vmu->pager)) {
05180       char *myserveremail = serveremail;
05181       if (!ast_strlen_zero(vmu->serveremail))
05182          myserveremail = vmu->serveremail;
05183       sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, duration, vmu, category);
05184    }
05185 
05186    if (ast_test_flag(vmu, VM_DELETE)) {
05187       DELETE(todir, msgnum, fn, vmu);
05188    }
05189 
05190    /* Leave voicemail for someone */
05191    if (ast_app_has_voicemail(ext_context, NULL)) {
05192       ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
05193    }
05194    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);
05195    run_externnotify(vmu->context, vmu->mailbox);
05196    return 0;
05197 }

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

Definition at line 2936 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

02937 {
02938    if (bio->linelength>=BASELINELEN) {
02939       if (fputs(eol,so)==EOF)
02940          return -1;
02941 
02942       bio->linelength= 0;
02943    }
02944 
02945    if (putc(((unsigned char)c),so)==EOF)
02946       return -1;
02947 
02948    bio->linelength++;
02949 
02950    return 1;
02951 }

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

Definition at line 5775 of file app_voicemail.c.

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

Referenced by vm_execmain().

05776 {
05777    int res = 0;
05778    int count_msg, last_msg;
05779 
05780    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
05781    
05782    /* Rename the member vmbox HERE so that we don't try to return before
05783     * we know what's going on.
05784     */
05785    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
05786    
05787    /* Faster to make the directory than to check if it exists. */
05788    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
05789 
05790    count_msg = count_messages(vmu, vms->curdir);
05791    if (count_msg < 0)
05792       return count_msg;
05793    else
05794       vms->lastmsg = count_msg - 1;
05795 
05796    /*
05797    The following test is needed in case sequencing gets messed up.
05798    There appears to be more than one way to mess up sequence, so
05799    we will not try to find all of the root causes--just fix it when
05800    detected.
05801    */
05802 
05803    last_msg = last_message_index(vmu, vms->curdir);
05804    if (last_msg < 0)
05805       return last_msg;
05806    else if (vms->lastmsg != last_msg)
05807    {
05808       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
05809       res = resequence_mailbox(vmu, vms->curdir);
05810       if (res)
05811          return res;
05812    }
05813 
05814    return 0;
05815 }

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

Definition at line 3613 of file app_voicemail.c.

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

Referenced by invent_message(), and leave_voicemail().

03614 {
03615    int res = -2;
03616 
03617 #ifdef ODBC_STORAGE
03618    int success = 
03619 #endif
03620    RETRIEVE(filename, -1, vmu);
03621    if (ast_fileexists(filename, NULL, NULL) > 0) {
03622       res = ast_streamfile(chan, filename, chan->language);
03623       if (res > -1) 
03624          res = ast_waitstream(chan, ecodes);
03625 #ifdef ODBC_STORAGE
03626       if (success == -1) {
03627          /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
03628          if (option_debug)
03629             ast_log(LOG_DEBUG, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
03630          store_file(filename, vmu->mailbox, vmu->context, -1);
03631       }
03632 #endif
03633    }
03634    DISPOSE(filename, -1);
03635 
03636    return res;
03637 }

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

Definition at line 5641 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_DEBUG, 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_he(), vm_browse_messages_latin(), and vm_execmain().

05642 {
05643    int res = 0;
05644    char filename[256], *cid;
05645    const char *origtime, *context, *category, *duration;
05646    struct ast_config *msg_cfg;
05647 
05648    vms->starting = 0; 
05649    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
05650    adsi_message(chan, vms);
05651    
05652    if (!strncasecmp(chan->language, "he", 2)) {        /* HEBREW FORMAT */
05653       /*
05654        * The syntax in hebrew for counting the number of message is up side down
05655        * in comparison to english.
05656        */
05657       if (!vms->curmsg) {
05658          res = wait_file2(chan, vms, "vm-message");
05659          res = wait_file2(chan, vms, "vm-first");    /* "First" */
05660       } else if (vms->curmsg == vms->lastmsg) {
05661          res = wait_file2(chan, vms, "vm-message");
05662          res = wait_file2(chan, vms, "vm-last");     /* "last" */
05663       } else {
05664          res = wait_file2(chan, vms, "vm-message");  /* "message" */
05665          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05666             ast_log(LOG_DEBUG, "curmsg: %d\n", vms->curmsg);
05667             ast_log(LOG_DEBUG, "lagmsg: %d\n", vms->lastmsg);
05668             if (!res) {
05669                res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
05670             }
05671          }
05672       }
05673 
05674    } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH FORMAT */
05675       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05676          int ten, one;
05677          char nextmsg[256];
05678          ten = (vms->curmsg + 1) / 10;
05679          one = (vms->curmsg + 1) % 10;
05680 
05681          if (vms->curmsg < 20) {
05682             snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
05683             res = wait_file2(chan, vms, nextmsg);
05684          } else {
05685             snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
05686             res = wait_file2(chan, vms, nextmsg);
05687             if (one > 0) {
05688                if (!res) {
05689                   snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
05690                   res = wait_file2(chan, vms, nextmsg);
05691                }
05692             }
05693          }
05694       }
05695       if (!res)
05696          res = wait_file2(chan, vms, "vm-message");         
05697 
05698    } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH FORMAT */
05699       if (!vms->curmsg)
05700          res = wait_file2(chan, vms, "vm-first");  /* "First" */
05701       else if (vms->curmsg == vms->lastmsg)
05702          res = wait_file2(chan, vms, "vm-last");      /* "last" */      
05703       res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
05704       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05705          if (!res)
05706             res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
05707       }
05708       /* We know that the difference between English and Swedish
05709        * is very small, however, we differ the two for standartization
05710        * purposes, and possible changes to either of these in the 
05711        * future
05712        */
05713    } else {
05714       if (!vms->curmsg)                      /* Default syntax */
05715          res = wait_file2(chan, vms, "vm-first");  /* "First" */
05716       else if (vms->curmsg == vms->lastmsg)
05717          res = wait_file2(chan, vms, "vm-last");      /* "last" */      
05718       res = wait_file2(chan, vms, "vm-message");
05719       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05720          if (!res)
05721             res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
05722       }
05723    }
05724 
05725    /* Retrieve info from VM attribute file */
05726    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
05727    snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
05728    RETRIEVE(vms->curdir, vms->curmsg, vmu);
05729    msg_cfg = ast_config_load(filename);
05730    if (!msg_cfg) {
05731       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
05732       return 0;
05733    }
05734 
05735    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
05736       ast_log(LOG_WARNING, "No origtime?!\n");
05737       DISPOSE(vms->curdir, vms->curmsg);
05738       ast_config_destroy(msg_cfg);
05739       return 0;
05740    }
05741 
05742    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
05743    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
05744    category = ast_variable_retrieve(msg_cfg, "message", "category");
05745 
05746    context = ast_variable_retrieve(msg_cfg, "message", "context");
05747    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
05748       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
05749    if (!res)
05750       res = play_message_category(chan, category);
05751    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
05752       res = play_message_datetime(chan, vmu, origtime, filename);
05753    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
05754       res = play_message_callerid(chan, vms, cid, context, 0);
05755    if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
05756       res = play_message_duration(chan, vms, duration, vmu->saydurationm);
05757    /* Allow pressing '1' to skip envelope / callerid */
05758    if (res == '1')
05759       res = 0;
05760    ast_config_destroy(msg_cfg);
05761 
05762    if (!res) {
05763       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
05764       vms->heard[vms->curmsg] = 1;
05765       if ((res = wait_file(chan, vms, vms->fn)) < 0) {
05766          ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn);
05767          res = 0;
05768       }
05769    }
05770    DISPOSE(vms->curdir, vms->curmsg);
05771    return res;
05772 }

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

Definition at line 5523 of file app_voicemail.c.

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

Referenced by advanced_options(), and play_message().

05524 {
05525    int res = 0;
05526    int i;
05527    char *callerid, *name;
05528    char prefile[PATH_MAX] = "";
05529    
05530 
05531    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
05532    /* 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 */
05533    if ((cid == NULL)||(context == NULL))
05534       return res;
05535 
05536    /* Strip off caller ID number from name */
05537    if (option_debug > 2)
05538       ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
05539    ast_callerid_parse(cid, &name, &callerid);
05540    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
05541       /* Check for internal contexts and only */
05542       /* say extension when the call didn't come from an internal context in the list */
05543       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
05544          if (option_debug > 2)
05545             ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
05546          if ((strcmp(cidinternalcontexts[i], context) == 0))
05547             break;
05548       }
05549       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
05550          if (!res) {
05551             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
05552             if (!ast_strlen_zero(prefile)) {
05553             /* See if we can find a recorded name for this person instead of their extension number */
05554                if (ast_fileexists(prefile, NULL, NULL) > 0) {
05555                   if (option_verbose > 2)
05556                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
05557                   if (!callback)
05558                      res = wait_file2(chan, vms, "vm-from");
05559                   res = ast_stream_and_wait(chan, prefile, chan->language, "");
05560                } else {
05561                   if (option_verbose > 2)
05562                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
05563                   /* BB: Say "from extension" as one saying to sound smoother */
05564                   if (!callback)
05565                      res = wait_file2(chan, vms, "vm-from-extension");
05566                   res = ast_say_digit_str(chan, callerid, "", chan->language);
05567                }
05568             }
05569          }
05570       }
05571 
05572       else if (!res){
05573          if (option_debug > 2)
05574             ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
05575          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
05576          if (!callback)
05577             res = wait_file2(chan, vms, "vm-from-phonenumber");
05578          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
05579       }
05580    } else {
05581       /* Number unknown */
05582       if (option_debug)
05583          ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
05584       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
05585       res = wait_file2(chan, vms, "vm-unknown-caller");
05586    }
05587    return res;
05588 }

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

Definition at line 5435 of file app_voicemail.c.

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

Referenced by play_message().

05436 {
05437    int res = 0;
05438 
05439    if (!ast_strlen_zero(category))
05440       res = ast_play_and_wait(chan, category);
05441 
05442    if (res) {
05443       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
05444       res = 0;
05445    }
05446 
05447    return res;
05448 }

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

Definition at line 5450 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_get_time_t(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), ast_say_date_with_format, ast_strlen_zero(), ast_tvnow(), ast_channel::language, vm_zone::list, vm_zone::msg_format, vm_zone::name, pbx_builtin_setvar_helper(), vm_zone::timezone, and ast_vm_user::zonetag.

Referenced by advanced_options(), and play_message().

05451 {
05452    int res = 0;
05453    struct vm_zone *the_zone = NULL;
05454    time_t t;
05455 
05456    if (ast_get_time_t(origtime, &t, 0, NULL)) {
05457       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
05458       return 0;
05459    }
05460 
05461    /* Does this user have a timezone specified? */
05462    if (!ast_strlen_zero(vmu->zonetag)) {
05463       /* Find the zone in the list */
05464       struct vm_zone *z;
05465       AST_LIST_LOCK(&zones);
05466       AST_LIST_TRAVERSE(&zones, z, list) {
05467          if (!strcmp(z->name, vmu->zonetag)) {
05468             the_zone = z;
05469             break;
05470          }
05471       }
05472       AST_LIST_UNLOCK(&zones);
05473    }
05474 
05475 /* No internal variable parsing for now, so we'll comment it out for the time being */
05476 #if 0
05477    /* Set the DIFF_* variables */
05478    ast_localtime(&t, &time_now, NULL);
05479    tv_now = ast_tvnow();
05480    tnow = tv_now.tv_sec;
05481    ast_localtime(&tnow, &time_then, NULL);
05482 
05483    /* Day difference */
05484    if (time_now.tm_year == time_then.tm_year)
05485       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
05486    else
05487       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
05488    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
05489 
05490    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
05491 #endif
05492    if (the_zone) {
05493       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
05494    } else if (!strncasecmp(chan->language, "de", 2)) {    /* GERMAN syntax */
05495       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05496    } else if (!strncasecmp(chan->language, "gr", 2)) {    /* GREEK syntax */
05497       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
05498    } else if (!strncasecmp(chan->language, "he", 2)) {    /* HEBREW syntax */
05499       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'at2' kM", NULL);
05500    } else if (!strncasecmp(chan->language, "it", 2)) {    /* ITALIAN syntax */
05501       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);
05502    } else if (!strncasecmp(chan->language, "nl", 2)) {    /* DUTCH syntax */
05503       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
05504    } else if (!strncasecmp(chan->language, "no", 2)) {    /* NORWEGIAN syntax */
05505       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05506    } else if (!strncasecmp(chan->language, "pl", 2)) {    /* POLISH syntax */
05507       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
05508    } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* PORTUGUESE syntax */
05509       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'digits/pt-de' B 'digits/pt-de' Y 'digits/pt-as' HM ", NULL);
05510    } else if (!strncasecmp(chan->language, "se", 2)) {    /* SWEDISH syntax */
05511       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
05512    } else {
05513       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
05514    }
05515 #if 0
05516    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
05517 #endif
05518    return res;
05519 }

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

Definition at line 5590 of file app_voicemail.c.

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

Referenced by play_message().

05591 {
05592    int res = 0;
05593    int durationm;
05594    int durations;
05595    /* Verify that we have a duration for the message */
05596    if (duration == NULL)
05597       return res;
05598 
05599    /* Convert from seconds to minutes */
05600    durations=atoi(duration);
05601    durationm=(durations / 60);
05602 
05603    if (option_debug > 2)
05604       ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
05605 
05606    if ((!res) && (durationm >= minduration)) {
05607       res = wait_file2(chan, vms, "vm-duration");
05608 
05609       /* POLISH syntax */
05610       if (!strncasecmp(chan->language, "pl", 2)) {
05611          div_t num = div(durationm, 10);
05612 
05613          if (durationm == 1) {
05614             res = ast_play_and_wait(chan, "digits/1z");
05615             res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
05616          } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05617             if (num.rem == 2) {
05618                if (!num.quot) {
05619                   res = ast_play_and_wait(chan, "digits/2-ie");
05620                } else {
05621                   res = say_and_wait(chan, durationm - 2 , chan->language);
05622                   res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05623                }
05624             } else {
05625                res = say_and_wait(chan, durationm, chan->language);
05626             }
05627             res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
05628          } else {
05629             res = say_and_wait(chan, durationm, chan->language);
05630             res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
05631          }
05632       /* DEFAULT syntax */
05633       } else {
05634          res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
05635          res = wait_file2(chan, vms, "vm-minutes");
05636       }
05637    }
05638    return res;
05639 }

static int play_record_review ( struct ast_channel chan,
char *  playfile,
char *  recordfile,
int  maxtime,
char *  fmt,
int  outsidecaller,
struct ast_vm_user vmu,
int *  duration,
const char *  unlockdir,
signed char  record_gain,
struct vm_state vms 
) [static]

Definition at line 9193 of file app_voicemail.c.

References ast_channel_setoption(), ast_copy_string(), AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_test_flag, ast_verbose(), ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, INTRO, ast_channel::language, 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().

09196 {
09197    /* Record message & let caller review or re-record it, or set options if applicable */
09198    int res = 0;
09199    int cmd = 0;
09200    int max_attempts = 3;
09201    int attempts = 0;
09202    int recorded = 0;
09203    int message_exists = 0;
09204    signed char zero_gain = 0;
09205    char tempfile[PATH_MAX];
09206    char *acceptdtmf = "#";
09207    char *canceldtmf = "";
09208 
09209    /* Note that urgent and private are for flagging messages as such in the future */
09210 
09211    /* barf if no pointer passed to store duration in */
09212    if (duration == NULL) {
09213       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
09214       return -1;
09215    }
09216 
09217    if (!outsidecaller)
09218       snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
09219    else
09220       ast_copy_string(tempfile, recordfile, sizeof(tempfile));
09221 
09222    cmd = '3';  /* Want to start by recording */
09223 
09224    while ((cmd >= 0) && (cmd != 't')) {
09225       switch (cmd) {
09226       case '1':
09227          if (!message_exists) {
09228             /* In this case, 1 is to record a message */
09229             cmd = '3';
09230             break;
09231          } else {
09232             /* Otherwise 1 is to save the existing message */
09233             if (option_verbose > 2)
09234                ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
09235             if (!outsidecaller)
09236                ast_filerename(tempfile, recordfile, NULL);
09237             ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
09238             if (!outsidecaller) {
09239                STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
09240                DISPOSE(recordfile, -1);
09241             }
09242             cmd = 't';
09243             return res;
09244          }
09245       case '2':
09246          /* Review */
09247          if (option_verbose > 2)
09248             ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
09249          cmd = ast_stream_and_wait(chan, tempfile, chan->language, AST_DIGIT_ANY);
09250          break;
09251       case '3':
09252          message_exists = 0;
09253          /* Record */
09254          if (recorded == 1) {
09255             if (option_verbose > 2)
09256                ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
09257          } else { 
09258             if (option_verbose > 2)
09259                ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
09260          }
09261          if (recorded && outsidecaller) {
09262             cmd = ast_play_and_wait(chan, INTRO);
09263             cmd = ast_play_and_wait(chan, "beep");
09264          }
09265          recorded = 1;
09266          /* 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 */
09267          if (record_gain)
09268             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
09269          if (ast_test_flag(vmu, VM_OPERATOR))
09270             canceldtmf = "0";
09271          cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
09272          if (record_gain)
09273             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
09274          if (cmd == -1) {
09275             /* User has hung up, no options to give */
09276             if (!outsidecaller) {
09277                /* user was recording a greeting and they hung up, so let's delete the recording. */
09278                ast_filedelete(tempfile, NULL);
09279             }
09280             return cmd;
09281          }
09282          if (cmd == '0') {
09283             break;
09284          } else if (cmd == '*') {
09285             break;
09286          } 
09287 #if 0       
09288          else if (vmu->review && (*duration < 5)) {
09289             /* Message is too short */
09290             if (option_verbose > 2)
09291                ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
09292             cmd = ast_play_and_wait(chan, "vm-tooshort");
09293             cmd = ast_filedelete(tempfile, NULL);
09294             break;
09295          }
09296          else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
09297             /* Message is all silence */
09298             if (option_verbose > 2)
09299                ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
09300             cmd = ast_filedelete(tempfile, NULL);
09301             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
09302             if (!cmd)
09303                cmd = ast_play_and_wait(chan, "vm-speakup");
09304             break;
09305          }
09306 #endif
09307          else {
09308             /* If all is well, a message exists */
09309             message_exists = 1;
09310             cmd = 0;
09311          }
09312          break;
09313       case '4':
09314       case '5':
09315       case '6':
09316       case '7':
09317       case '8':
09318       case '9':
09319       case '*':
09320       case '#':
09321          cmd = ast_play_and_wait(chan, "vm-sorry");
09322          break;
09323 #if 0 
09324 /*  XXX Commented out for the moment because of the dangers of deleting
09325     a message while recording (can put the message numbers out of sync) */
09326       case '*':
09327          /* Cancel recording, delete message, offer to take another message*/
09328          cmd = ast_play_and_wait(chan, "vm-deleted");
09329          cmd = ast_filedelete(tempfile, NULL);
09330          if (outsidecaller) {
09331             res = vm_exec(chan, NULL);
09332             return res;
09333          }
09334          else
09335             return 1;
09336 #endif
09337       case '0':
09338          if (!ast_test_flag(vmu, VM_OPERATOR)) {
09339             cmd = ast_play_and_wait(chan, "vm-sorry");
09340             break;
09341          }
09342          if (message_exists || recorded) {
09343             cmd = ast_play_and_wait(chan, "vm-saveoper");
09344             if (!cmd)
09345                cmd = ast_waitfordigit(chan, 3000);
09346             if (cmd == '1') {
09347                ast_play_and_wait(chan, "vm-msgsaved");
09348                cmd = '0';
09349             } else {
09350                ast_play_and_wait(chan, "vm-deleted");
09351                DELETE(recordfile, -1, recordfile, vmu);
09352                cmd = '0';
09353             }
09354          }
09355          return cmd;
09356       default:
09357          /* If the caller is an ouside caller, and the review option is enabled,
09358             allow them to review the message, but let the owner of the box review
09359             their OGM's */
09360          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
09361             return cmd;
09362          if (message_exists) {
09363             cmd = ast_play_and_wait(chan, "vm-review");
09364          }
09365          else {
09366             cmd = ast_play_and_wait(chan, "vm-torerecord");
09367             if (!cmd)
09368                cmd = ast_waitfordigit(chan, 600);
09369          }
09370          
09371          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
09372             cmd = ast_play_and_wait(chan, "vm-reachoper");
09373             if (!cmd)
09374                cmd = ast_waitfordigit(chan, 600);
09375          }
09376 #if 0
09377          if (!cmd)
09378             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
09379 #endif
09380          if (!cmd)
09381             cmd = ast_waitfordigit(chan, 6000);
09382          if (!cmd) {
09383             attempts++;
09384          }
09385          if (attempts > max_attempts) {
09386             cmd = 't';
09387          }
09388       }
09389    }
09390    if (outsidecaller)
09391       ast_play_and_wait(chan, "vm-goodbye");
09392    if (cmd == 't')
09393       cmd = 0;
09394    return cmd;
09395 }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

Definition at line 611 of file app_voicemail.c.

References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::exit, globalflags, ast_vm_user::maxmsg, ast_vm_user::saydurationm, ast_vm_user::volgain, and ast_vm_user::zonetag.

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

00612 {
00613    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00614    if (saydurationminfo)
00615       vmu->saydurationm = saydurationminfo;
00616    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00617    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00618    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00619    ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag));
00620    if (maxmsg)
00621       vmu->maxmsg = maxmsg;
00622    vmu->volgain = volgain;
00623 }

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

Definition at line 3025 of file app_voicemail.c.

References ast_callerid_merge(), ast_callerid_split(), ast_config_destroy(), ast_config_load(), ast_localtime(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_variable_retrieve(), ast_vm_user::context, ast_vm_user::fullname, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, and pbx_builtin_setvar_helper().

Referenced by make_email_file(), and sendpage().

03026 {
03027    char callerid[256];
03028    char fromdir[256], fromfile[256];
03029    struct ast_config *msg_cfg;
03030    const char *origcallerid, *origtime;
03031    char origcidname[80], origcidnum[80], origdate[80];
03032    int inttime;
03033 
03034    /* Prepare variables for substition in email body and subject */
03035    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
03036    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
03037    snprintf(passdata, passdatasize, "%d", msgnum);
03038    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
03039    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
03040    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
03041    pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ?
03042       ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller");
03043    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller"));
03044    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller"));
03045    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
03046    pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
03047 
03048    /* Retrieve info from VM attribute file */
03049    make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
03050    make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1);
03051    if (strlen(fromfile) < sizeof(fromfile) - 5) {
03052       strcat(fromfile, ".txt");
03053    }
03054    if (!(msg_cfg = ast_config_load(fromfile))) {
03055       if (option_debug > 0) {
03056          ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile);
03057       }
03058       return;
03059    }
03060 
03061    if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
03062       pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid);
03063       ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum));
03064       pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname);
03065       pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum);
03066    }
03067 
03068    if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) {
03069       time_t ttime = inttime;
03070       struct tm tm;
03071       ast_localtime(&ttime, &tm, NULL);
03072       strftime(origdate, sizeof(origdate), emaildateformat, &tm);
03073       pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate);
03074    }
03075    ast_config_destroy(msg_cfg);
03076 }

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

Definition at line 3078 of file app_voicemail.c.

03079 {
03080    char *ptr = to;
03081    *ptr++ = '"';
03082    for (; ptr < to + len - 1; from++) {
03083       if (*from == '"')
03084          *ptr++ = '\\';
03085       else if (*from == '\0')
03086          break;
03087       *ptr++ = *from;
03088    }
03089    if (ptr < to + len - 1)
03090       *ptr++ = '"';
03091    *ptr = '\0';
03092    return to;
03093 }

static int reload ( void   )  [static]

Definition at line 8879 of file app_voicemail.c.

References load_config().

08880 {
08881    return(load_config());
08882 }

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

Definition at line 2770 of file app_voicemail.c.

References ast_filerename().

02771 {
02772    char stxt[PATH_MAX];
02773    char dtxt[PATH_MAX];
02774    ast_filerename(sfn,dfn,NULL);
02775    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
02776    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
02777    rename(stxt, dtxt);
02778 }

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

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

04410 {
04411    /* we know max messages, so stop process when number is hit */
04412 
04413    int x,dest;
04414    char sfn[PATH_MAX];
04415    char dfn[PATH_MAX];
04416 
04417    if (vm_lock_path(dir))
04418       return ERROR_LOCK_PATH;
04419 
04420    for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
04421       make_file(sfn, sizeof(sfn), dir, x);
04422       if (EXISTS(dir, x, sfn, NULL)) {
04423          
04424          if (x != dest) {
04425             make_file(dfn, sizeof(dfn), dir, dest);
04426             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
04427          }
04428          
04429          dest++;
04430       }
04431    }
04432    ast_unlock_path(dir);
04433 
04434    return 0;
04435 }

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

Definition at line 829 of file app_voicemail.c.

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::context, ast_vm_user::list, ast_vm_user::mailbox, and ast_vm_user::password.

Referenced by vm_change_password(), and vm_change_password_shell().

00830 {
00831    /* This function could be made to generate one from a database, too */
00832    struct ast_vm_user *cur;
00833    int res = -1;
00834    AST_LIST_LOCK(&users);
00835    AST_LIST_TRAVERSE(&users, cur, list) {
00836       if ((!context || !strcasecmp(context, cur->context)) &&
00837          (!strcasecmp(mailbox, cur->mailbox)))
00838             break;
00839    }
00840    if (cur) {
00841       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00842       res = 0;
00843    }
00844    AST_LIST_UNLOCK(&users);
00845    return res;
00846 }

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

Definition at line 3976 of file app_voicemail.c.

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

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

03977 {
03978    char arguments[255];
03979    char ext_context[256] = "";
03980    int newvoicemails = 0, oldvoicemails = 0;
03981    struct ast_smdi_mwi_message *mwi_msg;
03982 
03983    if (!ast_strlen_zero(context))
03984       snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
03985    else
03986       ast_copy_string(ext_context, extension, sizeof(ext_context));
03987 
03988    if (!strcasecmp(externnotify, "smdi")) {
03989       if (ast_app_has_voicemail(ext_context, NULL)) 
03990          ast_smdi_mwi_set(smdi_iface, extension);
03991       else
03992          ast_smdi_mwi_unset(smdi_iface, extension);
03993 
03994       if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) {
03995          ast_log(LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension);
03996          if (!strncmp(mwi_msg->cause, "INV", 3))
03997             ast_log(LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
03998          else if (!strncmp(mwi_msg->cause, "BLK", 3))
03999             ast_log(LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
04000          ast_log(LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
04001          ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
04002       } else {
04003          if (option_debug)
04004             ast_log(LOG_DEBUG, "Successfully executed SMDI MWI change for %s\n", extension);
04005       }
04006    } else if (!ast_strlen_zero(externnotify)) {
04007       if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
04008          ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
04009       } else {
04010          snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
04011          if (option_debug)
04012             ast_log(LOG_DEBUG, "Executing %s\n", arguments);
04013          ast_safe_system(arguments);
04014       }
04015    }
04016 }

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

Definition at line 4445 of file app_voicemail.c.

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

Referenced by vm_execmain().

04446 {
04447 #ifdef IMAP_STORAGE
04448    /* we must use mbox(x) folder names, and copy the message there */
04449    /* simple. huh? */
04450    char sequence[10];
04451    /* get the real IMAP message number for this message */
04452    snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
04453    if (option_debug > 2)
04454       ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,(char *) mbox(box));
04455    ast_mutex_lock(&vms->lock);
04456    if (box == 1) {
04457       mail_setflag(vms->mailstream, sequence, "\\Seen");
04458    } else if (box == 0) {
04459       mail_clearflag(vms->mailstream, sequence, "\\Seen");
04460    }
04461    if (!strcasecmp(mbox(0), vms->curbox) && (box == 0 || box == 1)) {
04462       ast_mutex_unlock(&vms->lock);
04463       return 0;
04464    } else {
04465       int res = !mail_copy(vms->mailstream,sequence,(char *) mbox(box)); 
04466       ast_mutex_unlock(&vms->lock);
04467       return res;
04468    }
04469 #else
04470    char *dir = vms->curdir;
04471    char *username = vms->username;
04472    char *context = vmu->context;
04473    char sfn[PATH_MAX];
04474    char dfn[PATH_MAX];
04475    char ddir[PATH_MAX];
04476    const char *dbox = mbox(box);
04477    int x;
04478    make_file(sfn, sizeof(sfn), dir, msg);
04479    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
04480 
04481    if (vm_lock_path(ddir))
04482       return ERROR_LOCK_PATH;
04483 
04484    for (x = 0; x < vmu->maxmsg; x++) {
04485       make_file(dfn, sizeof(dfn), ddir, x);
04486       if (!EXISTS(ddir, x, dfn, NULL))
04487          break;
04488    }
04489    if (x >= vmu->maxmsg) {
04490       ast_unlock_path(ddir);
04491       return ERROR_MAILBOX_FULL;
04492    }
04493    if (strcmp(sfn, dfn)) {
04494       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
04495    }
04496    ast_unlock_path(ddir);
04497 #endif
04498    return 0;
04499 }

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

Definition at line 4438 of file app_voicemail.c.

References AST_DIGIT_ANY, and ast_say_number().

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

04439 {
04440    int d;
04441    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
04442    return d;
04443 }

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

Definition at line 3487 of file app_voicemail.c.

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

Referenced by forward_message(), and notify_new_message().

03488 {
03489    FILE *p=NULL;
03490    char tmp[80] = "/tmp/astmail-XXXXXX";
03491    char tmp2[256];
03492 
03493    if (vmu && ast_strlen_zero(vmu->email)) {
03494       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
03495       return(0);
03496    }
03497    if (!strcmp(format, "wav49"))
03498       format = "WAV";
03499    if (option_debug > 2)
03500       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));
03501    /* Make a temporary file instead of piping directly to sendmail, in case the mail
03502       command hangs */
03503    if ((p = vm_mkftemp(tmp)) == NULL) {
03504       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03505       return -1;
03506    } else {
03507       make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
03508       fclose(p);
03509       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03510       ast_safe_system(tmp2);
03511       if (option_debug > 2)
03512          ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
03513    }
03514    return 0;
03515 }

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

Definition at line 3517 of file app_voicemail.c.

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

Referenced by notify_new_message().

03518 {
03519    char date[256];
03520    char host[MAXHOSTNAMELEN] = "";
03521    char who[256];
03522    char dur[PATH_MAX];
03523    char tmp[80] = "/tmp/astmail-XXXXXX";
03524    char tmp2[PATH_MAX];
03525    struct tm tm;
03526    FILE *p;
03527 
03528    if ((p = vm_mkftemp(tmp)) == NULL) {
03529       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03530       return -1;
03531    } else {
03532       gethostname(host, sizeof(host)-1);
03533       if (strchr(srcemail, '@'))
03534          ast_copy_string(who, srcemail, sizeof(who));
03535       else {
03536          snprintf(who, sizeof(who), "%s@%s", srcemail, host);
03537       }
03538       snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
03539       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
03540       fprintf(p, "Date: %s\n", date);
03541 
03542       if (*pagerfromstring) {
03543          struct ast_channel *ast;
03544          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03545             char *passdata;
03546             int vmlen = strlen(fromstring)*3 + 200;
03547             if ((passdata = alloca(vmlen))) {
03548                memset(passdata, 0, vmlen);
03549                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03550                pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen);
03551                fprintf(p, "From: %s <%s>\n", passdata, who);
03552             } else 
03553                ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03554             ast_channel_free(ast);
03555          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03556       } else
03557          fprintf(p, "From: Asterisk PBX <%s>\n", who);
03558       fprintf(p, "To: %s\n", pager);
03559       if (pagersubject) {
03560          struct ast_channel *ast;
03561          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03562             char *passdata;
03563             int vmlen = strlen(pagersubject) * 3 + 200;
03564             if ((passdata = alloca(vmlen))) {
03565                memset(passdata, 0, vmlen);
03566                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03567                pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen);
03568                fprintf(p, "Subject: %s\n\n", passdata);
03569             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03570             ast_channel_free(ast);
03571          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03572       } else
03573          fprintf(p, "Subject: New VM\n\n");
03574       strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
03575       if (pagerbody) {
03576          struct ast_channel *ast;
03577          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03578             char *passdata;
03579             int vmlen = strlen(pagerbody)*3 + 200;
03580             if ((passdata = alloca(vmlen))) {
03581                memset(passdata, 0, vmlen);
03582                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03583                pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen);
03584                fprintf(p, "%s\n", passdata);
03585             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03586          ast_channel_free(ast);
03587          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03588       } else {
03589          fprintf(p, "New %s long msg in box %s\n"
03590                "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
03591       }
03592       fclose(p);
03593       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03594       ast_safe_system(tmp2);
03595       if (option_debug > 2)
03596          ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd);
03597    }
03598    return 0;
03599 }

static char* strip_control_and_high ( const char *  input,
char *  buf,
size_t  buflen 
) [static]

Strips control and non 7-bit clean characters from input string.

Note:
To map control and none 7-bit characters to a 7-bit clean characters please use ast_str_encode_mine().

Definition at line 595 of file app_voicemail.c.

Referenced by make_email_file().

00596 {
00597    char *bufptr = buf;
00598    for (; *input; input++) {
00599       if (*input < 32) {
00600          continue;
00601       }
00602       *bufptr++ = *input;
00603       if (bufptr == buf + buflen - 1) {
00604          break;
00605       }
00606    }
00607    *bufptr = '\0';
00608    return buf;
00609 }

static int unload_module ( void   )  [static]

Definition at line 8884 of file app_voicemail.c.

References ast_cli_unregister_multiple(), ast_module_user_hangup_all, ast_uninstall_vm_functions(), ast_unregister_application(), and cli_voicemail.

08885 {
08886    int res;
08887    
08888    res = ast_unregister_application(app);
08889    res |= ast_unregister_application(app2);
08890    res |= ast_unregister_application(app3);
08891    res |= ast_unregister_application(app4);
08892    ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08893    ast_uninstall_vm_functions();
08894    
08895    ast_module_user_hangup_all();
08896 
08897    return res;
08898 }

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

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

Referenced by vm_execmain(), and vmauthenticate().

07233 {
07234    int useadsi=0, valid=0, logretries=0;
07235    char password[AST_MAX_EXTENSION]="", *passptr;
07236    struct ast_vm_user vmus, *vmu = NULL;
07237 
07238    /* If ADSI is supported, setup login screen */
07239    adsi_begin(chan, &useadsi);
07240    if (!skipuser && useadsi)
07241       adsi_login(chan);
07242    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
07243       ast_log(LOG_WARNING, "Couldn't stream login file\n");
07244       return -1;
07245    }
07246    
07247    /* Authenticate them and get their mailbox/password */
07248    
07249    while (!valid && (logretries < maxlogins)) {
07250       /* Prompt for, and read in the username */
07251       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
07252          ast_log(LOG_WARNING, "Couldn't read username\n");
07253          return -1;
07254       }
07255       if (ast_strlen_zero(mailbox)) {
07256          if (chan->cid.cid_num) {
07257             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
07258          } else {
07259             if (option_verbose > 2)
07260                ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");  
07261             return -1;
07262          }
07263       }
07264       if (useadsi)
07265          adsi_password(chan);
07266 
07267       if (!ast_strlen_zero(prefix)) {
07268          char fullusername[80] = "";
07269          ast_copy_string(fullusername, prefix, sizeof(fullusername));
07270          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
07271          ast_copy_string(mailbox, fullusername, mailbox_size);
07272       }
07273 
07274       if (option_debug)
07275          ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
07276       vmu = find_user(&vmus, context, mailbox);
07277       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
07278          /* saved password is blank, so don't bother asking */
07279          password[0] = '\0';
07280       } else {
07281          if (ast_streamfile(chan, "vm-password", chan->language)) {
07282             ast_log(LOG_WARNING, "Unable to stream password file\n");
07283             return -1;
07284          }
07285          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
07286             ast_log(LOG_WARNING, "Unable to read password\n");
07287             return -1;
07288          }
07289       }
07290 
07291       if (vmu) {
07292          passptr = vmu->password;
07293          if (passptr[0] == '-') passptr++;
07294       }
07295       if (vmu && !strcmp(passptr, password))
07296          valid++;
07297       else {
07298          if (option_verbose > 2)
07299             ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
07300          if (!ast_strlen_zero(prefix))
07301             mailbox[0] = '\0';
07302       }
07303       logretries++;
07304       if (!valid) {
07305          if (skipuser || logretries >= maxlogins) {
07306             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
07307                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
07308                return -1;
07309             }
07310          } else {
07311             if (useadsi)
07312                adsi_login(chan);
07313             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
07314                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
07315                return -1;
07316             }
07317          }
07318          if (ast_waitstream(chan, "")) /* Channel is hung up */
07319             return -1;
07320       }
07321    }
07322    if (!valid && (logretries >= maxlogins)) {
07323       ast_stopstream(chan);
07324       ast_play_and_wait(chan, "vm-goodbye");
07325       return -1;
07326    }
07327    if (vmu && !skipuser) {
07328       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
07329    }
07330    return 0;
07331 }

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

Definition at line 8066 of file app_voicemail.c.

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

Referenced by load_module().

08067 {
08068    struct ast_module_user *u;
08069    struct ast_vm_user svm;
08070    char *context, *box;
08071    int priority_jump = 0;
08072    AST_DECLARE_APP_ARGS(args,
08073       AST_APP_ARG(mbox);
08074       AST_APP_ARG(options);
08075    );
08076 
08077    if (ast_strlen_zero(data)) {
08078       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
08079       return -1;
08080    }
08081 
08082    u = ast_module_user_add(chan);
08083 
08084    box = ast_strdupa(data);
08085 
08086    AST_STANDARD_APP_ARGS(args, box);
08087 
08088    if (args.options) {
08089       if (strchr(args.options, 'j'))
08090          priority_jump = 1;
08091    }
08092 
08093    if ((context = strchr(args.mbox, '@'))) {
08094       *context = '\0';
08095       context++;
08096    }
08097 
08098    if (find_user(&svm, context, args.mbox)) {
08099       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
08100       if (priority_jump || ast_opt_priority_jumping)
08101          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
08102             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);
08103    } else
08104       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
08105    ast_module_user_remove(u);
08106    return 0;
08107 }

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

Definition at line 7216 of file app_voicemail.c.

References ast_channel::language, vm_browse_messages_en(), vm_browse_messages_he(), and vm_browse_messages_latin().

Referenced by vm_execmain().

07217 {
07218    if (!strncasecmp(chan->language, "es", 2) ||
07219          !strncasecmp(chan->language, "it", 2) ||
07220          !strncasecmp(chan->language, "pt", 2) ||
07221          !strncasecmp(chan->language, "gr", 2)) { /* SPANISH, ITALIAN, PORTUGUESE or GREEK */
07222       return vm_browse_messages_latin(chan, vms, vmu);
07223    } else if (!strncasecmp(chan->language, "he", 2)) {  /* HEBREW */
07224       return vm_browse_messages_he(chan, vms, vmu);
07225    } else {                                             /* Default to English syntax */
07226       return vm_browse_messages_en(chan, vms, vmu);
07227    }
07228 }

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

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

07152 {
07153    int cmd=0;
07154 
07155    if (vms->lastmsg > -1) {
07156       cmd = play_message(chan, vmu, vms);
07157    } else {
07158       cmd = ast_play_and_wait(chan, "vm-youhave");
07159       if (!cmd) 
07160          cmd = ast_play_and_wait(chan, "vm-no");
07161       if (!cmd) {
07162          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07163          cmd = ast_play_and_wait(chan, vms->fn);
07164       }
07165       if (!cmd)
07166          cmd = ast_play_and_wait(chan, "vm-messages");
07167    }
07168    return cmd;
07169 }

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

Definition at line 7172 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07173 {
07174    int cmd = 0;
07175 
07176    if (vms->lastmsg > -1) {
07177       cmd = play_message(chan, vmu, vms);
07178    } else {
07179       if (!strcasecmp(vms->fn, "INBOX")) {
07180          cmd = ast_play_and_wait(chan, "vm-nonewmessages");
07181       } else {
07182          cmd = ast_play_and_wait(chan, "vm-nomessages");
07183       }
07184    }
07185    return cmd;
07186 }

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

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

07190 {
07191    int cmd=0;
07192 
07193    if (vms->lastmsg > -1) {
07194       cmd = play_message(chan, vmu, vms);
07195    } else {
07196       cmd = ast_play_and_wait(chan, "vm-youhaveno");
07197       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
07198          if (!cmd) {
07199             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
07200             cmd = ast_play_and_wait(chan, vms->fn);
07201          }
07202          if (!cmd)
07203             cmd = ast_play_and_wait(chan, "vm-messages");
07204       } else {
07205          if (!cmd)
07206             cmd = ast_play_and_wait(chan, "vm-messages");
07207          if (!cmd) {
07208             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07209             cmd = ast_play_and_wait(chan, vms->fn);
07210          }
07211       }
07212    }
07213    return cmd;
07214 }

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

Definition at line 848 of file app_voicemail.c.

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

Referenced by vm_newuser(), and vm_options().

00849 {
00850    struct ast_config   *cfg=NULL;
00851    struct ast_variable *var=NULL;
00852    struct ast_category *cat=NULL;
00853    char *category=NULL, *value=NULL, *new=NULL;
00854    const char *tmp=NULL;
00855                
00856    if (!change_password_realtime(vmu, newpassword))
00857       return;
00858 
00859    /* check voicemail.conf */
00860    if ((cfg = ast_config_load_with_comments(VOICEMAIL_CONFIG))) {
00861       while ((category = ast_category_browse(cfg, category))) {
00862          if (!strcasecmp(category, vmu->context)) {
00863             tmp = ast_variable_retrieve(cfg, category, vmu->mailbox);
00864             if (!tmp) {
00865                ast_log(LOG_WARNING, "We could not find the mailbox.\n");
00866                break;
00867             }
00868             value = strstr(tmp,",");
00869             if (!value) {
00870                ast_log(LOG_WARNING, "variable has bad format.\n");
00871                break;
00872             }
00873             new = alloca((strlen(value)+strlen(newpassword)+1));
00874             sprintf(new,"%s%s", newpassword, value);
00875             if (!(cat = ast_category_get(cfg, category))) {
00876                ast_log(LOG_WARNING, "Failed to get category structure.\n");
00877                break;
00878             }
00879             ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
00880          }
00881       }
00882       /* save the results */
00883       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00884       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00885       config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
00886    }
00887    category = NULL;
00888    var = NULL;
00889    /* check users.conf and update the password stored for the mailbox*/
00890    /* if no vmsecret entry exists create one. */
00891    if ((cfg = ast_config_load_with_comments("users.conf"))) {
00892       if (option_debug > 3)
00893          ast_log(LOG_DEBUG, "we are looking for %s\n", vmu->mailbox);
00894       while ((category = ast_category_browse(cfg, category))) {
00895          if (option_debug > 3)
00896             ast_log(LOG_DEBUG, "users.conf: %s\n", category);
00897          if (!strcasecmp(category, vmu->mailbox)) {
00898             if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) {
00899                if (option_debug > 3)
00900                   ast_log(LOG_DEBUG, "looks like we need to make vmsecret!\n");
00901                var = ast_variable_new("vmsecret", newpassword);
00902             } 
00903             new = alloca(strlen(newpassword)+1);
00904             sprintf(new, "%s", newpassword);
00905             if (!(cat = ast_category_get(cfg, category))) {
00906                if (option_debug > 3)
00907                   ast_log(LOG_DEBUG, "failed to get category!\n");
00908                break;
00909             }
00910             if (!var)      
00911                ast_variable_update(cat, "vmsecret", new, NULL, 0);
00912             else
00913                ast_variable_append(cat, var);
00914          }
00915       }
00916       /* save the results and clean things up */
00917       reset_user_pw(vmu->context, vmu->mailbox, newpassword);  
00918       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00919       config_text_file_save("users.conf", cfg, "AppVoicemail");
00920    }
00921 }

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

Definition at line 923 of file app_voicemail.c.

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

00924 {
00925    char buf[255];
00926    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00927    if (!ast_safe_system(buf)) {
00928       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00929       /* Reset the password in memory, too */
00930       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00931    }
00932 }

static int vm_delete ( char *  file  )  [static]

Definition at line 2890 of file app_voicemail.c.

References ast_filedelete().

Referenced by copy_message(), and forward_message().

02891 {
02892    char *txt;
02893    int txtsize = 0;
02894 
02895    txtsize = (strlen(file) + 5)*sizeof(char);
02896    txt = alloca(txtsize);
02897    /* Sprintf here would safe because we alloca'd exactly the right length,
02898     * but trying to eliminate all sprintf's anyhow
02899     */
02900    snprintf(txt, txtsize, "%s.txt", file);
02901    unlink(txt);
02902    return ast_filedelete(file, NULL);
02903 }

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

Definition at line 7911 of file app_voicemail.c.

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

Referenced by load_module(), and play_record_review().

07912 {
07913    int res = 0;
07914    struct ast_module_user *u;
07915    char *tmp;
07916    struct leave_vm_options leave_options;
07917    struct ast_flags flags = { 0 };
07918    static int deprecate_warning = 0;
07919    char *opts[OPT_ARG_ARRAY_SIZE];
07920    AST_DECLARE_APP_ARGS(args,
07921       AST_APP_ARG(argv0);
07922       AST_APP_ARG(argv1);
07923    );
07924 
07925    u = ast_module_user_add(chan);
07926    
07927    memset(&leave_options, 0, sizeof(leave_options));
07928 
07929    if (chan->_state != AST_STATE_UP)
07930       ast_answer(chan);
07931 
07932    if (!ast_strlen_zero(data)) {
07933       tmp = ast_strdupa(data);
07934       AST_STANDARD_APP_ARGS(args, tmp);
07935       if (args.argc == 2) {
07936          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
07937             ast_module_user_remove(u);
07938             return -1;
07939          }
07940          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
07941          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07942             int gain;
07943 
07944             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
07945                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07946                ast_module_user_remove(u);
07947                return -1;
07948             } else {
07949                leave_options.record_gain = (signed char) gain;
07950             }
07951          }
07952       } else {
07953          /* old style options parsing */
07954          int old = 0;
07955          char *orig_argv0 = args.argv0;
07956          while (*(args.argv0)) {
07957             if (*(args.argv0) == 's') {
07958                old = 1;
07959                ast_set_flag(&leave_options, OPT_SILENT);
07960             } else if (*(args.argv0) == 'b') {
07961                old = 1;
07962                ast_set_flag(&leave_options, OPT_BUSY_GREETING);
07963             } else if (*(args.argv0) == 'u') {
07964                old = 1;
07965                ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
07966             } else if (*(args.argv0) == 'j') {
07967                old = 1;
07968                ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
07969             } else
07970                break;
07971             (args.argv0)++;
07972          }
07973          if (!deprecate_warning && old) {
07974             deprecate_warning = 1;
07975             ast_log(LOG_WARNING, "Prefixing the mailbox with an option is deprecated ('%s').\n", orig_argv0);
07976             ast_log(LOG_WARNING, "Please move all leading options to the second argument.\n");
07977          }
07978       }
07979    } else {
07980       char tmp[256];
07981       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
07982       if (res < 0) {
07983          ast_module_user_remove(u);
07984          return res;
07985       }
07986       if (ast_strlen_zero(tmp)) {
07987          ast_module_user_remove(u);
07988          return 0;
07989       }
07990       args.argv0 = ast_strdupa(tmp);
07991    }
07992 
07993    res = leave_voicemail(chan, args.argv0, &leave_options);
07994 
07995    if (res == ERROR_LOCK_PATH) {
07996       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
07997       /*Send the call to n+101 priority, where n is the current priority*/
07998       if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
07999          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
08000             ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
08001       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
08002       res = 0;
08003    }
08004    
08005    ast_module_user_remove(u);
08006 
08007    return res;
08008 }

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

Definition at line 7333 of file app_voicemail.c.

References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), advanced_options(), ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_parse_options(), ast_calloc, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), ast_module_user_add, ast_module_user_remove, ast_mutex_lock(), ast_mutex_unlock(), ast_play_and_wait(), ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_waitfordigit(), ast_vm_user::callback, close_mailbox(), ast_vm_user::context, create_dirpath(), dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), ast_flags::flags, forward_message(), free, free_user(), get_folder2(), globalflags, has_voicemail(), language, ast_vm_user::language, LOG_DEBUG, ast_vm_user::mailbox, make_file(), manager_event(), ast_vm_user::maxmsg, open_mailbox(), OPT_ARG_ARRAY_SIZE, OPT_ARG_PLAYFOLDER, OPT_ARG_RECORDGAIN, OPT_AUTOPLAY, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, option_debug, option_verbose, parse(), ast_vm_user::password, play_message(), run_externnotify(), save_to_folder(), say_and_wait(), VERBOSE_PREFIX_3, vm_app_options, vm_authenticate(), vm_browse_messages(), VM_FORCEGREET, VM_FORCENAME, vm_instructions(), vm_intro(), vm_newuser(), vm_options(), vm_play_folder_name(), VM_SKIPAFTERCMD, and VM_SVMAIL.

Referenced by load_module().

07334 {
07335    /* XXX This is, admittedly, some pretty horrendus code.  For some
07336       reason it just seemed a lot easier to do with GOTO's.  I feel
07337       like I'm back in my GWBASIC days. XXX */
07338    int res=-1;
07339    int cmd=0;
07340    int valid = 0;
07341    struct ast_module_user *u;
07342    char prefixstr[80] ="";
07343    char ext_context[256]="";
07344    int box;
07345    int useadsi = 0;
07346    int skipuser = 0;
07347    struct vm_state vms;
07348    struct ast_vm_user *vmu = NULL, vmus;
07349    char *context=NULL;
07350    int silentexit = 0;
07351    struct ast_flags flags = { 0 };
07352    signed char record_gain = 0;
07353    int play_auto = 0;
07354    int play_folder = 0;
07355 #ifdef IMAP_STORAGE
07356    int deleted = 0;
07357 #endif
07358    u = ast_module_user_add(chan);
07359 
07360    /* Add the vm_state to the active list and keep it active */
07361    memset(&vms, 0, sizeof(vms));
07362    vms.lastmsg = -1;
07363 
07364    memset(&vmus, 0, sizeof(vmus));
07365 
07366    if (chan->_state != AST_STATE_UP) {
07367       if (option_debug)
07368          ast_log(LOG_DEBUG, "Before ast_answer\n");
07369       ast_answer(chan);
07370    }
07371 
07372    if (!ast_strlen_zero(data)) {
07373       char *opts[OPT_ARG_ARRAY_SIZE];
07374       char *parse;
07375       AST_DECLARE_APP_ARGS(args,
07376          AST_APP_ARG(argv0);
07377          AST_APP_ARG(argv1);
07378       );
07379 
07380       parse = ast_strdupa(data);
07381 
07382       AST_STANDARD_APP_ARGS(args, parse);
07383 
07384       if (args.argc == 2) {
07385          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
07386             ast_module_user_remove(u);
07387             return -1;
07388          }
07389          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07390             int gain;
07391             if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
07392                if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
07393                   ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07394                   ast_module_user_remove(u);
07395                   return -1;
07396                } else {
07397                   record_gain = (signed char) gain;
07398                }
07399             } else {
07400                ast_log(LOG_WARNING, "Invalid Gain level set with option g\n");
07401             }
07402          }
07403          if (ast_test_flag(&flags, OPT_AUTOPLAY) ) {
07404             play_auto = 1;
07405             if (opts[OPT_ARG_PLAYFOLDER]) {
07406                if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) {
07407                   ast_log(LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]);
07408                }
07409             } else {
07410                ast_log(LOG_WARNING, "Invalid folder set with option a\n");
07411             }  
07412             if ( play_folder > 9 || play_folder < 0) {
07413                ast_log(LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder);
07414                play_folder = 0;
07415             }
07416          }
07417       } else {
07418          /* old style options parsing */
07419          while (*(args.argv0)) {
07420             if (*(args.argv0) == 's')
07421                ast_set_flag(&flags, OPT_SILENT);
07422             else if (*(args.argv0) == 'p')
07423                ast_set_flag(&flags, OPT_PREPEND_MAILBOX);
07424             else 
07425                break;
07426             (args.argv0)++;
07427          }
07428 
07429       }
07430 
07431       valid = ast_test_flag(&flags, OPT_SILENT);
07432 
07433       if ((context = strchr(args.argv0, '@')))
07434          *context++ = '\0';
07435 
07436       if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
07437          ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr));
07438       else
07439          ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
07440 
07441       if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
07442          skipuser++;
07443       else
07444          valid = 0;
07445    }
07446 
07447    if (!valid)
07448       res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
07449 
07450    if (option_debug)
07451       ast_log(LOG_DEBUG, "After vm_authenticate\n");
07452    if (!res) {
07453       valid = 1;
07454       if (!skipuser)
07455          vmu = &vmus;
07456    } else {
07457       res = 0;
07458    }
07459 
07460    /* If ADSI is supported, setup login screen */
07461    adsi_begin(chan, &useadsi);
07462 
07463    if (!valid) {
07464       goto out;
07465    }
07466 
07467 #ifdef IMAP_STORAGE
07468    pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
07469    pthread_setspecific(ts_vmstate.key, &vms);
07470 
07471    vms.interactive = 1;
07472    vms.updated = 1;
07473    if (vmu)
07474       ast_copy_string(vms.context, vmu->context, sizeof(vms.context));
07475    vmstate_insert(&vms);
07476    init_vm_state(&vms);
07477 #endif
07478    if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) {
07479       /* TODO: Handle memory allocation failure */
07480    }
07481    if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) {
07482       /* TODO: Handle memory allocation failure */
07483    }
07484    
07485    /* Set language from config to override channel language */
07486    if (!ast_strlen_zero(vmu->language))
07487       ast_string_field_set(chan, language, vmu->language);
07488    create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
07489    /* Retrieve old and new message counts */
07490    if (option_debug)
07491       ast_log(LOG_DEBUG, "Before open_mailbox\n");
07492    res = open_mailbox(&vms, vmu, 1);
07493    if (res == ERROR_LOCK_PATH)
07494       goto out;
07495    vms.oldmessages = vms.lastmsg + 1;
07496    if (option_debug > 2)
07497       ast_log(LOG_DEBUG, "Number of old messages: %d\n",vms.oldmessages);
07498    /* Start in INBOX */
07499    res = open_mailbox(&vms, vmu, 0);
07500    if (res == ERROR_LOCK_PATH)
07501       goto out;
07502    vms.newmessages = vms.lastmsg + 1;
07503    if (option_debug > 2)
07504       ast_log(LOG_DEBUG, "Number of new messages: %d\n",vms.newmessages);
07505       
07506    /* Select proper mailbox FIRST!! */
07507    if (play_auto) {
07508       res = open_mailbox(&vms, vmu, play_folder);
07509       if (res == ERROR_LOCK_PATH)
07510          goto out;
07511 
07512       /* If there are no new messages, inform the user and hangup */
07513       if (vms.lastmsg == -1) {
07514          cmd = vm_browse_messages(chan, &vms, vmu);
07515          res = 0;
07516          goto out;
07517       }
07518    } else {
07519       if (!vms.newmessages && vms.oldmessages) {
07520          /* If we only have old messages start here */
07521          res = open_mailbox(&vms, vmu, 1);
07522          play_folder = 1;
07523          if (res == ERROR_LOCK_PATH)
07524             goto out;
07525       }
07526    }
07527 
07528    if (useadsi)
07529       adsi_status(chan, &vms);
07530    res = 0;
07531 
07532    /* Check to see if this is a new user */
07533    if (!strcasecmp(vmu->mailbox, vmu->password) && 
07534       (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) {
07535       if (ast_play_and_wait(chan, "vm-newuser") == -1)
07536          ast_log(LOG_WARNING, "Couldn't stream new user file\n");
07537       cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
07538       if ((cmd == 't') || (cmd == '#')) {
07539          /* Timeout */
07540          res = 0;
07541          goto out;
07542       } else if (cmd < 0) {
07543          /* Hangup */
07544          res = -1;
07545          goto out;
07546       }
07547    }
07548 #ifdef IMAP_STORAGE
07549       if (option_debug > 2)
07550          ast_log(LOG_DEBUG, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit);
07551       if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
07552          if (option_debug)
07553             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!!\n");
07554          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07555       }
07556       if (option_debug > 2)
07557          ast_log(LOG_DEBUG, "Checking quotas: User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
07558       if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) {
07559          ast_log(LOG_WARNING, "No more messages possible.  User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
07560          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07561       }
07562 #endif
07563    if (play_auto) {
07564       cmd = '1';
07565    } else {
07566       cmd = vm_intro(chan, vmu, &vms);
07567    }
07568 
07569    vms.repeats = 0;
07570    vms.starting = 1;
07571    while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
07572       /* Run main menu */
07573       switch (cmd) {
07574       case '1':
07575          vms.curmsg = 0;
07576          /* Fall through */
07577       case '5':
07578          cmd = vm_browse_messages(chan, &vms, vmu);
07579          break;
07580       case '2': /* Change folders */
07581          if (useadsi)
07582             adsi_folders(chan, 0, "Change to folder...");
07583          cmd = get_folder2(chan, "vm-changeto", 0);
07584          if (cmd == '#') {
07585             cmd = 0;
07586          } else if (cmd > 0) {
07587             cmd = cmd - '0';
07588             res = close_mailbox(&vms, vmu);
07589             if (res == ERROR_LOCK_PATH)
07590                goto out;
07591             res = open_mailbox(&vms, vmu, cmd);
07592             if (res == ERROR_LOCK_PATH)
07593                goto out;
07594             play_folder = cmd;
07595             cmd = 0;
07596          }
07597          if (useadsi)
07598             adsi_status2(chan, &vms);
07599             
07600          if (!cmd)
07601             cmd = vm_play_folder_name(chan, vms.vmbox);
07602 
07603          vms.starting = 1;
07604          break;
07605       case '3': /* Advanced options */
07606          cmd = 0;
07607          vms.repeats = 0;
07608          while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
07609             switch (cmd) {
07610             case '1': /* Reply */
07611                if (vms.lastmsg > -1 && !vms.starting) {
07612                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
07613                   if (cmd == ERROR_LOCK_PATH) {
07614                      res = cmd;
07615                      goto out;
07616                   }
07617                } else
07618                   cmd = ast_play_and_wait(chan, "vm-sorry");
07619                cmd = 't';
07620                break;
07621             case '2': /* Callback */
07622                if (option_verbose > 2 && !vms.starting)
07623                   ast_verbose( VERBOSE_PREFIX_3 "Callback Requested\n");
07624                if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
07625                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
07626                   if (cmd == 9) {
07627                      silentexit = 1;
07628                      goto out;
07629                   } else if (cmd == ERROR_LOCK_PATH) {
07630                      res = cmd;
07631                      goto out;
07632                   }
07633                }
07634                else 
07635                   cmd = ast_play_and_wait(chan, "vm-sorry");
07636                cmd = 't';
07637                break;
07638             case '3': /* Envelope */
07639                if (vms.lastmsg > -1 && !vms.starting) {
07640                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
07641                   if (cmd == ERROR_LOCK_PATH) {
07642                      res = cmd;
07643                      goto out;
07644                   }
07645                } else
07646                   cmd = ast_play_and_wait(chan, "vm-sorry");
07647                cmd = 't';
07648                break;
07649             case '4': /* Dialout */
07650                if (!ast_strlen_zero(vmu->dialout)) {
07651                   cmd = dialout(chan, vmu, NULL, vmu->dialout);
07652                   if (cmd == 9) {
07653                      silentexit = 1;
07654                      goto out;
07655                   }
07656                }
07657                else 
07658                   cmd = ast_play_and_wait(chan, "vm-sorry");
07659                cmd = 't';
07660                break;
07661 
07662             case '5': /* Leave VoiceMail */
07663                if (ast_test_flag(vmu, VM_SVMAIL)) {
07664                   cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
07665                   if (cmd == ERROR_LOCK_PATH) {
07666                      res = cmd;
07667                      ast_log(LOG_WARNING, "forward_message failed to lock path.\n");
07668                      goto out;
07669                   }
07670                } else
07671                   cmd = ast_play_and_wait(chan,"vm-sorry");
07672                cmd='t';
07673                break;
07674                
07675             case '*': /* Return to main menu */
07676                cmd = 't';
07677                break;
07678 
07679             default:
07680                cmd = 0;
07681                if (!vms.starting) {
07682                   cmd = ast_play_and_wait(chan, "vm-toreply");
07683                }
07684                if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
07685                   cmd = ast_play_and_wait(chan, "vm-tocallback");
07686                }
07687                if (!cmd && !vms.starting) {
07688                   cmd = ast_play_and_wait(chan, "vm-tohearenv");
07689                }
07690                if (!ast_strlen_zero(vmu->dialout) && !cmd) {
07691                   cmd = ast_play_and_wait(chan, "vm-tomakecall");
07692                }
07693                if (ast_test_flag(vmu, VM_SVMAIL) && !cmd)
07694                   cmd=ast_play_and_wait(chan, "vm-leavemsg");
07695                if (!cmd)
07696                   cmd = ast_play_and_wait(chan, "vm-starmain");
07697                if (!cmd)
07698                   cmd = ast_waitfordigit(chan,6000);
07699                if (!cmd)
07700                   vms.repeats++;
07701                if (vms.repeats > 3)
07702                   cmd = 't';
07703             }
07704          }
07705          if (cmd == 't') {
07706             cmd = 0;
07707             vms.repeats = 0;
07708          }
07709          break;
07710       case '4':
07711          if (vms.curmsg > 0) {
07712             vms.curmsg--;
07713             cmd = play_message(chan, vmu, &vms);
07714          } else {
07715             cmd = ast_play_and_wait(chan, "vm-nomore");
07716          }
07717          break;
07718       case '6':
07719          if (vms.curmsg < vms.lastmsg) {
07720             vms.curmsg++;
07721             cmd = play_message(chan, vmu, &vms);
07722          } else {
07723             cmd = ast_play_and_wait(chan, "vm-nomore");
07724          }
07725          break;
07726       case '7':
07727          if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
07728             vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
07729             if (useadsi)
07730                adsi_delete(chan, &vms);
07731             if (vms.deleted[vms.curmsg]) {
07732                if (play_folder == 0)
07733                   vms.newmessages--;
07734                else if (play_folder == 1)
07735                   vms.oldmessages--;
07736                cmd = ast_play_and_wait(chan, "vm-deleted");
07737             }
07738             else {
07739                if (play_folder == 0)
07740                   vms.newmessages++;
07741                else if (play_folder == 1)
07742                   vms.oldmessages++;
07743                cmd = ast_play_and_wait(chan, "vm-undeleted");
07744             }
07745             if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
07746                if (vms.curmsg < vms.lastmsg) {
07747                   vms.curmsg++;
07748                   cmd = play_message(chan, vmu, &vms);
07749                } else {
07750                   cmd = ast_play_and_wait(chan, "vm-nomore");
07751                }
07752             }
07753          } else /* Delete not valid if we haven't selected a message */
07754             cmd = 0;
07755 #ifdef IMAP_STORAGE
07756          deleted = 1;
07757 #endif
07758          break;
07759    
07760       case '8':
07761          if (vms.lastmsg > -1) {
07762             cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain);
07763             if (cmd == ERROR_LOCK_PATH) {
07764                res = cmd;
07765                goto out;
07766             }
07767          } else
07768             cmd = ast_play_and_wait(chan, "vm-nomore");
07769          break;
07770       case '9':
07771          if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) {
07772             /* No message selected */
07773             cmd = 0;
07774             break;
07775          }
07776          if (useadsi)
07777             adsi_folders(chan, 1, "Save to folder...");
07778          cmd = get_folder2(chan, "vm-savefolder", 1);
07779          box = 0; /* Shut up compiler */
07780          if (cmd == '#') {
07781             cmd = 0;
07782             break;
07783          } else if (cmd > 0) {
07784             box = cmd = cmd - '0';
07785             cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd);
07786             if (cmd == ERROR_LOCK_PATH) {
07787                res = cmd;
07788                goto out;
07789 #ifndef IMAP_STORAGE
07790             } else if (!cmd) {
07791                vms.deleted[vms.curmsg] = 1;
07792 #endif
07793             } else {
07794                vms.deleted[vms.curmsg] = 0;
07795                vms.heard[vms.curmsg] = 0;
07796             }
07797          }
07798          make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
07799          if (useadsi)
07800             adsi_message(chan, &vms);
07801          snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
07802          if (!cmd) {
07803             cmd = ast_play_and_wait(chan, "vm-message");
07804             if (!cmd)
07805                cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
07806             if (!cmd)
07807                cmd = ast_play_and_wait(chan, "vm-savedto");
07808             if (!cmd)
07809                cmd = vm_play_folder_name(chan, vms.fn);
07810          } else {
07811             cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07812          }
07813          if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
07814             if (vms.curmsg < vms.lastmsg) {
07815                vms.curmsg++;
07816                cmd = play_message(chan, vmu, &vms);
07817             } else {
07818                cmd = ast_play_and_wait(chan, "vm-nomore");
07819             }
07820          }
07821          break;
07822       case '*':
07823          if (!vms.starting) {
07824             cmd = ast_play_and_wait(chan, "vm-onefor");
07825             if (!strncasecmp(chan->language, "he", 2)) {
07826                cmd = ast_play_and_wait(chan, "vm-for");
07827             }
07828             if (!cmd)
07829                cmd = vm_play_folder_name(chan, vms.vmbox);
07830             if (!cmd)
07831                cmd = ast_play_and_wait(chan, "vm-opts");
07832             if (!cmd)
07833                cmd = vm_instructions(chan, &vms, 1);
07834          } else
07835             cmd = 0;
07836          break;
07837       case '0':
07838          cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
07839          if (useadsi)
07840             adsi_status(chan, &vms);
07841          break;
07842       default: /* Nothing */
07843          cmd = vm_instructions(chan, &vms, 0);
07844          break;
07845       }
07846    }
07847    if ((cmd == 't') || (cmd == '#')) {
07848       /* Timeout */
07849       res = 0;
07850    } else {
07851       /* Hangup */
07852       res = -1;
07853    }
07854 
07855 out:
07856    if (res > -1) {
07857       ast_stopstream(chan);
07858       adsi_goodbye(chan);
07859       if (valid) {
07860          if (silentexit)
07861             res = ast_play_and_wait(chan, "vm-dialout");
07862          else 
07863             res = ast_play_and_wait(chan, "vm-goodbye");
07864          if (res > 0)
07865             res = 0;
07866       }
07867       if (useadsi)
07868          ast_adsi_unload_session(chan);
07869    }
07870    if (vmu)
07871       close_mailbox(&vms, vmu);
07872    if (valid) {
07873       snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
07874       manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
07875       run_externnotify(vmu->context, vmu->mailbox);
07876    }
07877 #ifdef IMAP_STORAGE
07878    /* expunge message - use UID Expunge if supported on IMAP server*/
07879    if (option_debug > 2)
07880       ast_log(LOG_DEBUG, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup);
07881    if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) {
07882       ast_mutex_lock(&vms.lock);
07883 #ifdef HAVE_IMAP_TK2006
07884       if (LEVELUIDPLUS (vms.mailstream)) {
07885          mail_expunge_full(vms.mailstream,NIL,EX_UID);
07886       } else 
07887 #endif
07888          mail_expunge(vms.mailstream);
07889       ast_mutex_unlock(&vms.lock);
07890    }
07891    /*  before we delete the state, we should copy pertinent info
07892     *  back to the persistent model */
07893    if (vmu) {
07894       vmstate_delete(&vms);
07895    }
07896 #endif
07897    if (vmu)
07898       free_user(vmu);
07899    if (vms.deleted)
07900       free(vms.deleted);
07901    if (vms.heard)
07902       free(vms.heard);
07903 
07904 #ifdef IMAP_STORAGE
07905    pthread_setspecific(ts_vmstate.key, NULL);
07906 #endif
07907    ast_module_user_remove(u);
07908    return res;
07909 }

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

Definition at line 5037 of file app_voicemail.c.

References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load(), ast_filecopy(), ast_filedelete(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), config_text_file_save(), and make_file().

Referenced by forward_message().

05039 {
05040    int cmd = 0;
05041    int retries = 0, prepend_duration = 0, already_recorded = 0;
05042    signed char zero_gain = 0;
05043    struct ast_config *msg_cfg;
05044    const char *duration_str;
05045    char msgfile[PATH_MAX], backup[PATH_MAX];
05046    char textfile[PATH_MAX];
05047 
05048    /* Must always populate duration correctly */
05049    make_file(msgfile, sizeof(msgfile), curdir, curmsg);
05050    strcpy(textfile, msgfile);
05051    strcpy(backup, msgfile);
05052    strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
05053    strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
05054 
05055    if (!(msg_cfg = ast_config_load(textfile))) {
05056       return -1;
05057    }
05058 
05059    *duration = 0;
05060    if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
05061       *duration = atoi(duration_str);
05062 
05063    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
05064       if (cmd)
05065          retries = 0;
05066       switch (cmd) {
05067       case '1': 
05068          /* prepend a message to the current message, update the metadata and return */
05069       {
05070          prepend_duration = 0;
05071 
05072          /* if we can't read the message metadata, stop now */
05073          if (!msg_cfg) {
05074             cmd = 0;
05075             break;
05076          }
05077 
05078          /* Back up the original file, so we can retry the prepend */
05079          if (already_recorded)
05080             ast_filecopy(backup, msgfile, NULL);
05081          else
05082             ast_filecopy(msgfile, backup, NULL);
05083          already_recorded = 1;
05084 
05085          if (record_gain)
05086             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
05087 
05088          cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
05089          if (record_gain)
05090             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
05091 
05092          if (prepend_duration) {
05093             struct ast_category *msg_cat;
05094             /* need enough space for a maximum-length message duration */
05095             char duration_str[12];
05096 
05097             prepend_duration += *duration;
05098             msg_cat = ast_category_get(msg_cfg, "message");
05099             snprintf(duration_str, 11, "%d", prepend_duration);
05100             if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
05101                config_text_file_save(textfile, msg_cfg, "app_voicemail");
05102             }
05103          }
05104 
05105          break;
05106       }
05107       case '2': 
05108          cmd = 't';
05109          break;
05110       case '*':
05111          cmd = '*';
05112          break;
05113       default: 
05114          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
05115             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
05116          if (!cmd)
05117             cmd = ast_play_and_wait(chan,"vm-starmain");
05118             /* "press star to return to the main menu" */
05119          if (!cmd)
05120             cmd = ast_waitfordigit(chan,6000);
05121          if (!cmd)
05122             retries++;
05123          if (retries > 3)
05124             cmd = 't';
05125       }
05126    }
05127 
05128    ast_config_destroy(msg_cfg);
05129    if (already_recorded)
05130       ast_filedelete(backup, NULL);
05131    if (prepend_duration)
05132       *duration = prepend_duration;
05133 
05134    if (cmd == 't' || cmd == 'S')
05135       cmd = 0;
05136    return cmd;
05137 }

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

Definition at line 6839 of file app_voicemail.c.

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

Referenced by vm_execmain().

06840 {
06841    int res = 0;
06842    /* Play instructions and wait for new command */
06843    while (!res) {
06844       if (vms->starting) {
06845          if (vms->lastmsg > -1) {
06846             res = ast_play_and_wait(chan, "vm-onefor");
06847             if (!strncasecmp(chan->language, "he", 2)) {
06848                res = ast_play_and_wait(chan, "vm-for");
06849             }
06850             if (!res)
06851                res = vm_play_folder_name(chan, vms->vmbox);
06852          }
06853          if (!res)
06854             res = ast_play_and_wait(chan, "vm-opts");
06855       } else {
06856          if (vms->curmsg)
06857             res = ast_play_and_wait(chan, "vm-prev");
06858          if (!res && !skipadvanced)
06859             res = ast_play_and_wait(chan, "vm-advopts");
06860          if (!res)
06861             res = ast_play_and_wait(chan, "vm-repeat");
06862          if (!res && (vms->curmsg != vms->lastmsg))
06863             res = ast_play_and_wait(chan, "vm-next");
06864          if (!res) {
06865             if (!vms->deleted[vms->curmsg])
06866                res = ast_play_and_wait(chan, "vm-delete");
06867             else
06868                res = ast_play_and_wait(chan, "vm-undelete");
06869             if (!res)
06870                res = ast_play_and_wait(chan, "vm-toforward");
06871             if (!res)
06872                res = ast_play_and_wait(chan, "vm-savemessage");
06873          }
06874       }
06875       if (!res)
06876          res = ast_play_and_wait(chan, "vm-helpexit");
06877       if (!res)
06878          res = ast_waitfordigit(chan, 6000);
06879       if (!res) {
06880          vms->repeats++;
06881          if (vms->repeats > 2) {
06882             res = 't';
06883          }
06884       }
06885    }
06886    return res;
06887 }

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

Definition at line 6783 of file app_voicemail.c.

References ast_fileexists(), ast_log(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, DISPOSE, ast_channel::language, RETRIEVE, vm_state::username, vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_he(), vm_intro_it(), vm_intro_multilang(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_se(), and VM_TEMPGREETWARN.

Referenced by vm_execmain().

06784 {
06785    char prefile[256];
06786    
06787    /* Notify the user that the temp greeting is set and give them the option to remove it */
06788    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06789    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
06790       RETRIEVE(prefile, -1, vmu);
06791       if (ast_fileexists(prefile, NULL, NULL) > 0)
06792          ast_play_and_wait(chan, "vm-tempgreetactive");
06793       DISPOSE(prefile, -1);
06794    }
06795 
06796    /* Play voicemail intro - syntax is different for different languages */
06797    if (0) {
06798    } else if (!strncasecmp(chan->language, "cs", 2)) {  /* CZECH syntax */
06799       return vm_intro_cs(chan, vms);
06800    } else if (!strncasecmp(chan->language, "cz", 2)) {  /* deprecated CZECH syntax */
06801       static int deprecation_warning = 0;
06802       if (deprecation_warning++ % 10 == 0) {
06803          ast_log(LOG_WARNING, "cz is not a standard language code.  Please switch to using cs instead.\n");
06804       }
06805       return vm_intro_cs(chan, vms);
06806    } else if (!strncasecmp(chan->language, "de", 2)) {  /* GERMAN syntax */
06807       return vm_intro_de(chan, vms);
06808    } else if (!strncasecmp(chan->language, "es", 2)) {  /* SPANISH syntax */
06809       return vm_intro_es(chan, vms);
06810    } else if (!strncasecmp(chan->language, "fr", 2)) {  /* FRENCH syntax */
06811       return vm_intro_fr(chan, vms);
06812    } else if (!strncasecmp(chan->language, "gr", 2)) {  /* GREEK syntax */
06813       return vm_intro_gr(chan, vms);
06814    } else if (!strncasecmp(chan->language, "he", 2)) {  /* HEBREW syntax */
06815       return vm_intro_he(chan, vms);
06816    } else if (!strncasecmp(chan->language, "it", 2)) {  /* ITALIAN syntax */
06817       return vm_intro_it(chan, vms);
06818    } else if (!strncasecmp(chan->language, "nl", 2)) {  /* DUTCH syntax */
06819       return vm_intro_nl(chan, vms);
06820    } else if (!strncasecmp(chan->language, "no", 2)) {  /* NORWEGIAN syntax */
06821       return vm_intro_no(chan, vms);
06822    } else if (!strncasecmp(chan->language, "pl", 2)) {  /* POLISH syntax */
06823       return vm_intro_pl(chan, vms);
06824    } else if (!strncasecmp(chan->language, "pt_BR", 5)) {  /* BRAZILIAN PORTUGUESE syntax */
06825       return vm_intro_pt_BR(chan, vms);
06826    } else if (!strncasecmp(chan->language, "pt", 2)) {  /* PORTUGUESE syntax */
06827       return vm_intro_pt(chan, vms);
06828    } else if (!strncasecmp(chan->language, "ru", 2)) {  /* RUSSIAN syntax */
06829       return vm_intro_multilang(chan, vms, "n");
06830    } else if (!strncasecmp(chan->language, "se", 2)) {  /* SWEDISH syntax */
06831       return vm_intro_se(chan, vms);
06832    } else if (!strncasecmp(chan->language, "ua", 2)) {  /* UKRAINIAN syntax */
06833       return vm_intro_multilang(chan, vms, "n");
06834    } else {                                             /* Default to ENGLISH */
06835       return vm_intro_en(chan, vms);
06836    }
06837 }

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

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

06724 {
06725    int res;
06726    res = ast_play_and_wait(chan, "vm-youhave");
06727    if (!res) {
06728       if (vms->newmessages) {
06729          if (vms->newmessages == 1) {
06730             res = ast_play_and_wait(chan, "digits/jednu");
06731          } else {
06732             res = say_and_wait(chan, vms->newmessages, chan->language);
06733          }
06734          if (!res) {
06735             if ((vms->newmessages == 1))
06736                res = ast_play_and_wait(chan, "vm-novou");
06737             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
06738                res = ast_play_and_wait(chan, "vm-nove");
06739             if (vms->newmessages > 4)
06740                res = ast_play_and_wait(chan, "vm-novych");
06741          }
06742          if (vms->oldmessages && !res)
06743             res = ast_play_and_wait(chan, "vm-and");
06744          else if (!res) {
06745             if ((vms->newmessages == 1))
06746                res = ast_play_and_wait(chan, "vm-zpravu");
06747             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
06748                res = ast_play_and_wait(chan, "vm-zpravy");
06749             if (vms->newmessages > 4)
06750                res = ast_play_and_wait(chan, "vm-zprav");
06751          }
06752       }
06753       if (!res && vms->oldmessages) {
06754          res = say_and_wait(chan, vms->oldmessages, chan->language);
06755          if (!res) {
06756             if ((vms->oldmessages == 1))
06757                res = ast_play_and_wait(chan, "vm-starou");
06758             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
06759                res = ast_play_and_wait(chan, "vm-stare");
06760             if (vms->oldmessages > 4)
06761                res = ast_play_and_wait(chan, "vm-starych");
06762          }
06763          if (!res) {
06764             if ((vms->oldmessages == 1))
06765                res = ast_play_and_wait(chan, "vm-zpravu");
06766             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
06767                res = ast_play_and_wait(chan, "vm-zpravy");
06768             if (vms->oldmessages > 4)
06769                res = ast_play_and_wait(chan, "vm-zprav");
06770          }
06771       }
06772       if (!res) {
06773          if (!vms->oldmessages && !vms->newmessages) {
06774             res = ast_play_and_wait(chan, "vm-no");
06775             if (!res)
06776                res = ast_play_and_wait(chan, "vm-zpravy");
06777          }
06778       }
06779    }
06780    return res;
06781 }

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

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

06417 {
06418    /* Introduce messages they have */
06419    int res;
06420    res = ast_play_and_wait(chan, "vm-youhave");
06421    if (!res) {
06422       if (vms->newmessages) {
06423          if ((vms->newmessages == 1))
06424             res = ast_play_and_wait(chan, "digits/1F");
06425          else
06426             res = say_and_wait(chan, vms->newmessages, chan->language);
06427          if (!res)
06428             res = ast_play_and_wait(chan, "vm-INBOX");
06429          if (vms->oldmessages && !res)
06430             res = ast_play_and_wait(chan, "vm-and");
06431          else if (!res) {
06432             if ((vms->newmessages == 1))
06433                res = ast_play_and_wait(chan, "vm-message");
06434             else
06435                res = ast_play_and_wait(chan, "vm-messages");
06436          }
06437             
06438       }
06439       if (!res && vms->oldmessages) {
06440          if (vms->oldmessages == 1)
06441             res = ast_play_and_wait(chan, "digits/1F");
06442          else
06443             res = say_and_wait(chan, vms->oldmessages, chan->language);
06444          if (!res)
06445             res = ast_play_and_wait(chan, "vm-Old");
06446          if (!res) {
06447             if (vms->oldmessages == 1)
06448                res = ast_play_and_wait(chan, "vm-message");
06449             else
06450                res = ast_play_and_wait(chan, "vm-messages");
06451          }
06452       }
06453       if (!res) {
06454          if (!vms->oldmessages && !vms->newmessages) {
06455             res = ast_play_and_wait(chan, "vm-no");
06456             if (!res)
06457                res = ast_play_and_wait(chan, "vm-messages");
06458          }
06459       }
06460    }
06461    return res;
06462 }

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

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

06015 {
06016    int res;
06017 
06018    /* Introduce messages they have */
06019    res = ast_play_and_wait(chan, "vm-youhave");
06020    if (!res) {
06021       if (vms->newmessages) {
06022          res = say_and_wait(chan, vms->newmessages, chan->language);
06023          if (!res)
06024             res = ast_play_and_wait(chan, "vm-INBOX");
06025          if (vms->oldmessages && !res)
06026             res = ast_play_and_wait(chan, "vm-and");
06027          else if (!res) {
06028             if ((vms->newmessages == 1))
06029                res = ast_play_and_wait(chan, "vm-message");
06030             else
06031                res = ast_play_and_wait(chan, "vm-messages");
06032          }
06033             
06034       }
06035       if (!res && vms->oldmessages) {
06036          res = say_and_wait(chan, vms->oldmessages, chan->language);
06037          if (!res)
06038             res = ast_play_and_wait(chan, "vm-Old");
06039          if (!res) {
06040             if (vms->oldmessages == 1)
06041                res = ast_play_and_wait(chan, "vm-message");
06042             else
06043                res = ast_play_and_wait(chan, "vm-messages");
06044          }
06045       }
06046       if (!res) {
06047          if (!vms->oldmessages && !vms->newmessages) {
06048             res = ast_play_and_wait(chan, "vm-no");
06049             if (!res)
06050                res = ast_play_and_wait(chan, "vm-messages");
06051          }
06052       }
06053    }
06054    return res;
06055 }

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

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

06466 {
06467    /* Introduce messages they have */
06468    int res;
06469    if (!vms->oldmessages && !vms->newmessages) {
06470       res = ast_play_and_wait(chan, "vm-youhaveno");
06471       if (!res)
06472          res = ast_play_and_wait(chan, "vm-messages");
06473    } else {
06474       res = ast_play_and_wait(chan, "vm-youhave");
06475    }
06476    if (!res) {
06477       if (vms->newmessages) {
06478          if (!res) {
06479             if ((vms->newmessages == 1)) {
06480                res = ast_play_and_wait(chan, "digits/1");
06481                if (!res)
06482                   res = ast_play_and_wait(chan, "vm-message");
06483                if (!res)
06484                   res = ast_play_and_wait(chan, "vm-INBOXs");
06485             } else {
06486                res = say_and_wait(chan, vms->newmessages, chan->language);
06487                if (!res)
06488                   res = ast_play_and_wait(chan, "vm-messages");
06489                if (!res)
06490                   res = ast_play_and_wait(chan, "vm-INBOX");
06491             }
06492          }
06493          if (vms->oldmessages && !res)
06494             res = ast_play_and_wait(chan, "vm-and");
06495       }
06496       if (vms->oldmessages) {
06497          if (!res) {
06498             if (vms->oldmessages == 1) {
06499                res = ast_play_and_wait(chan, "digits/1");
06500                if (!res)
06501                   res = ast_play_and_wait(chan, "vm-message");
06502                if (!res)
06503                   res = ast_play_and_wait(chan, "vm-Olds");
06504             } else {
06505                res = say_and_wait(chan, vms->oldmessages, chan->language);
06506                if (!res)
06507                   res = ast_play_and_wait(chan, "vm-messages");
06508                if (!res)
06509                   res = ast_play_and_wait(chan, "vm-Old");
06510             }
06511          }
06512       }
06513    }
06514 return res;
06515 }

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

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

06567 {
06568    /* Introduce messages they have */
06569    int res;
06570    res = ast_play_and_wait(chan, "vm-youhave");
06571    if (!res) {
06572       if (vms->newmessages) {
06573          res = say_and_wait(chan, vms->newmessages, chan->language);
06574          if (!res)
06575             res = ast_play_and_wait(chan, "vm-INBOX");
06576          if (vms->oldmessages && !res)
06577             res = ast_play_and_wait(chan, "vm-and");
06578          else if (!res) {
06579             if ((vms->newmessages == 1))
06580                res = ast_play_and_wait(chan, "vm-message");
06581             else
06582                res = ast_play_and_wait(chan, "vm-messages");
06583          }
06584             
06585       }
06586       if (!res && vms->oldmessages) {
06587          res = say_and_wait(chan, vms->oldmessages, chan->language);
06588          if (!res)
06589             res = ast_play_and_wait(chan, "vm-Old");
06590          if (!res) {
06591             if (vms->oldmessages == 1)
06592                res = ast_play_and_wait(chan, "vm-message");
06593             else
06594                res = ast_play_and_wait(chan, "vm-messages");
06595          }
06596       }
06597       if (!res) {
06598          if (!vms->oldmessages && !vms->newmessages) {
06599             res = ast_play_and_wait(chan, "vm-no");
06600             if (!res)
06601                res = ast_play_and_wait(chan, "vm-messages");
06602          }
06603       }
06604    }
06605    return res;
06606 }

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

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

05977 {
05978    int res = 0;
05979 
05980    if (vms->newmessages) {
05981       res = ast_play_and_wait(chan, "vm-youhave");
05982       if (!res) 
05983          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
05984       if (!res) {
05985          if ((vms->newmessages == 1)) {
05986             res = ast_play_and_wait(chan, "vm-INBOX");
05987             if (!res)
05988                res = ast_play_and_wait(chan, "vm-message");
05989          } else {
05990             res = ast_play_and_wait(chan, "vm-INBOXs");
05991             if (!res)
05992                res = ast_play_and_wait(chan, "vm-messages");
05993          }
05994       }
05995    } else if (vms->oldmessages){
05996       res = ast_play_and_wait(chan, "vm-youhave");
05997       if (!res)
05998          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
05999       if ((vms->oldmessages == 1)){
06000          res = ast_play_and_wait(chan, "vm-Old");
06001          if (!res)
06002             res = ast_play_and_wait(chan, "vm-message");
06003       } else {
06004          res = ast_play_and_wait(chan, "vm-Olds");
06005          if (!res)
06006             res = ast_play_and_wait(chan, "vm-messages");
06007       }
06008    } else if (!vms->oldmessages && !vms->newmessages) 
06009       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
06010    return res;
06011 }

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

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

06155 {
06156    int res=0;
06157 
06158    /* Introduce messages they have */
06159    if (!res) {
06160       if ((vms->newmessages) || (vms->oldmessages)) {
06161          res = ast_play_and_wait(chan, "vm-youhave");
06162       }
06163       /*
06164        * The word "shtei" refers to the number 2 in hebrew when performing a count
06165        * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for
06166        * an element, this is one of them.
06167        */
06168       if (vms->newmessages) {
06169          if (!res) {
06170             if (vms->newmessages == 1) {
06171                res = ast_play_and_wait(chan, "vm-INBOX1");
06172             } else {
06173                if (vms->newmessages == 2) {
06174                   res = ast_play_and_wait(chan, "vm-shtei");
06175                } else {
06176                   res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06177                }
06178                res = ast_play_and_wait(chan, "vm-INBOX");
06179             }
06180          }
06181          if (vms->oldmessages && !res) {
06182             res = ast_play_and_wait(chan, "vm-and");
06183             if (vms->oldmessages == 1) {
06184                res = ast_play_and_wait(chan, "vm-Old1");
06185             } else {
06186                if (vms->oldmessages == 2) {
06187                   res = ast_play_and_wait(chan, "vm-shtei");
06188                } else {
06189                   res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06190                }
06191                res = ast_play_and_wait(chan, "vm-Old");
06192             }
06193          }
06194       }
06195       if (!res && vms->oldmessages && !vms->newmessages) {
06196          if (!res) {
06197             if (vms->oldmessages == 1) {
06198                res = ast_play_and_wait(chan, "vm-Old1");
06199             } else {
06200                if (vms->oldmessages == 2) {
06201                   res = ast_play_and_wait(chan, "vm-shtei");
06202                } else {
06203                   res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");            
06204                }
06205                res = ast_play_and_wait(chan, "vm-Old");
06206             }
06207          }
06208       }
06209       if (!res) {
06210          if (!vms->oldmessages && !vms->newmessages) {
06211             if (!res) {
06212                res = ast_play_and_wait(chan, "vm-nomessages");
06213             }
06214          }
06215       }
06216    }
06217    return res;
06218 }

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

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

06223 {
06224    /* Introduce messages they have */
06225    int res;
06226    if (!vms->oldmessages && !vms->newmessages)
06227       res = ast_play_and_wait(chan, "vm-no") ||
06228          ast_play_and_wait(chan, "vm-message");
06229    else
06230       res = ast_play_and_wait(chan, "vm-youhave");
06231    if (!res && vms->newmessages) {
06232       res = (vms->newmessages == 1) ?
06233          ast_play_and_wait(chan, "digits/un") ||
06234          ast_play_and_wait(chan, "vm-nuovo") ||
06235          ast_play_and_wait(chan, "vm-message") :
06236          /* 2 or more new messages */
06237          say_and_wait(chan, vms->newmessages, chan->language) ||
06238          ast_play_and_wait(chan, "vm-nuovi") ||
06239          ast_play_and_wait(chan, "vm-messages");
06240       if (!res && vms->oldmessages)
06241          res = ast_play_and_wait(chan, "vm-and");
06242    }
06243    if (!res && vms->oldmessages) {
06244       res = (vms->oldmessages == 1) ?
06245          ast_play_and_wait(chan, "digits/un") ||
06246          ast_play_and_wait(chan, "vm-vecchio") ||
06247          ast_play_and_wait(chan, "vm-message") :
06248          /* 2 or more old messages */
06249          say_and_wait(chan, vms->oldmessages, chan->language) ||
06250          ast_play_and_wait(chan, "vm-vecchi") ||
06251          ast_play_and_wait(chan, "vm-messages");
06252    }
06253    return res;
06254 }

static int vm_intro_multilang ( struct ast_channel chan,
struct vm_state vms,
const char  message_gender[] 
) [static]

Definition at line 6114 of file app_voicemail.c.

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

Referenced by vm_intro().

06115 {
06116    int res;
06117    int lastnum = 0;
06118 
06119    res = ast_play_and_wait(chan, "vm-youhave");
06120 
06121    if (!res && vms->newmessages) {
06122       lastnum = vms->newmessages;
06123 
06124       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06125          res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender);
06126       }
06127 
06128       if (!res && vms->oldmessages) {
06129          res = ast_play_and_wait(chan, "vm-and");
06130       }
06131    }
06132 
06133    if (!res && vms->oldmessages) {
06134       lastnum = vms->oldmessages;
06135 
06136       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06137          res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender);
06138       }
06139    }
06140 
06141    if (!res) {
06142       if (lastnum == 0) {
06143          res = ast_play_and_wait(chan, "vm-no");
06144       }
06145       if (!res) {
06146          res = ast_say_counted_noun(chan, lastnum, "vm-message");
06147       }
06148    }
06149 
06150    return res;
06151 }

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

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

06610 {
06611    /* Introduce messages they have */
06612    int res;
06613    res = ast_play_and_wait(chan, "vm-youhave");
06614    if (!res) {
06615       if (vms->newmessages) {
06616          res = say_and_wait(chan, vms->newmessages, chan->language);
06617          if (!res) {
06618             if (vms->newmessages == 1)
06619                res = ast_play_and_wait(chan, "vm-INBOXs");
06620             else
06621                res = ast_play_and_wait(chan, "vm-INBOX");
06622          }
06623          if (vms->oldmessages && !res)
06624             res = ast_play_and_wait(chan, "vm-and");
06625          else if (!res) {
06626             if ((vms->newmessages == 1))
06627                res = ast_play_and_wait(chan, "vm-message");
06628             else
06629                res = ast_play_and_wait(chan, "vm-messages");
06630          }
06631             
06632       }
06633       if (!res && vms->oldmessages) {
06634          res = say_and_wait(chan, vms->oldmessages, chan->language);
06635          if (!res) {
06636             if (vms->oldmessages == 1)
06637                res = ast_play_and_wait(chan, "vm-Olds");
06638             else
06639                res = ast_play_and_wait(chan, "vm-Old");
06640          }
06641          if (!res) {
06642             if (vms->oldmessages == 1)
06643                res = ast_play_and_wait(chan, "vm-message");
06644             else
06645                res = ast_play_and_wait(chan, "vm-messages");
06646          }
06647       }
06648       if (!res) {
06649          if (!vms->oldmessages && !vms->newmessages) {
06650             res = ast_play_and_wait(chan, "vm-no");
06651             if (!res)
06652                res = ast_play_and_wait(chan, "vm-messages");
06653          }
06654       }
06655    }
06656    return res;
06657 }

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

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

06373 {
06374    /* Introduce messages they have */
06375    int res;
06376 
06377    res = ast_play_and_wait(chan, "vm-youhave");
06378    if (res)
06379       return res;
06380 
06381    if (!vms->oldmessages && !vms->newmessages) {
06382       res = ast_play_and_wait(chan, "vm-no");
06383       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06384       return res;
06385    }
06386 
06387    if (vms->newmessages) {
06388       if ((vms->newmessages == 1)) {
06389          res = ast_play_and_wait(chan, "digits/1");
06390          res = res ? res : ast_play_and_wait(chan, "vm-ny");
06391          res = res ? res : ast_play_and_wait(chan, "vm-message");
06392       } else {
06393          res = say_and_wait(chan, vms->newmessages, chan->language);
06394          res = res ? res : ast_play_and_wait(chan, "vm-nye");
06395          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06396       }
06397       if (!res && vms->oldmessages)
06398          res = ast_play_and_wait(chan, "vm-and");
06399    }
06400    if (!res && vms->oldmessages) {
06401       if (vms->oldmessages == 1) {
06402          res = ast_play_and_wait(chan, "digits/1");
06403          res = res ? res : ast_play_and_wait(chan, "vm-gamel");
06404          res = res ? res : ast_play_and_wait(chan, "vm-message");
06405       } else {
06406          res = say_and_wait(chan, vms->oldmessages, chan->language);
06407          res = res ? res : ast_play_and_wait(chan, "vm-gamle");
06408          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06409       }
06410    }
06411 
06412    return res;
06413 }

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

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

06258 {
06259    /* Introduce messages they have */
06260    int res;
06261    div_t num;
06262 
06263    if (!vms->oldmessages && !vms->newmessages) {
06264       res = ast_play_and_wait(chan, "vm-no");
06265       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06266       return res;
06267    } else {
06268       res = ast_play_and_wait(chan, "vm-youhave");
06269    }
06270 
06271    if (vms->newmessages) {
06272       num = div(vms->newmessages, 10);
06273       if (vms->newmessages == 1) {
06274          res = ast_play_and_wait(chan, "digits/1-a");
06275          res = res ? res : ast_play_and_wait(chan, "vm-new-a");
06276          res = res ? res : ast_play_and_wait(chan, "vm-message");
06277       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06278          if (num.rem == 2) {
06279             if (!num.quot) {
06280                res = ast_play_and_wait(chan, "digits/2-ie");
06281             } else {
06282                res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
06283                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06284             }
06285          } else {
06286             res = say_and_wait(chan, vms->newmessages, chan->language);
06287          }
06288          res = res ? res : ast_play_and_wait(chan, "vm-new-e");
06289          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06290       } else {
06291          res = say_and_wait(chan, vms->newmessages, chan->language);
06292          res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
06293          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06294       }
06295       if (!res && vms->oldmessages)
06296          res = ast_play_and_wait(chan, "vm-and");
06297    }
06298    if (!res && vms->oldmessages) {
06299       num = div(vms->oldmessages, 10);
06300       if (vms->oldmessages == 1) {
06301          res = ast_play_and_wait(chan, "digits/1-a");
06302          res = res ? res : ast_play_and_wait(chan, "vm-old-a");
06303          res = res ? res : ast_play_and_wait(chan, "vm-message");
06304       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06305          if (num.rem == 2) {
06306             if (!num.quot) {
06307                res = ast_play_and_wait(chan, "digits/2-ie");
06308             } else {
06309                res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
06310                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06311             }
06312          } else {
06313             res = say_and_wait(chan, vms->oldmessages, chan->language);
06314          }
06315          res = res ? res : ast_play_and_wait(chan, "vm-old-e");
06316          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06317       } else {
06318          res = say_and_wait(chan, vms->oldmessages, chan->language);
06319          res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
06320          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06321       }
06322    }
06323 
06324    return res;
06325 }

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

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

06661 {
06662    /* Introduce messages they have */
06663    int res;
06664    res = ast_play_and_wait(chan, "vm-youhave");
06665    if (!res) {
06666       if (vms->newmessages) {
06667          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06668          if (!res) {
06669             if ((vms->newmessages == 1)) {
06670                res = ast_play_and_wait(chan, "vm-message");
06671                if (!res)
06672                   res = ast_play_and_wait(chan, "vm-INBOXs");
06673             } else {
06674                res = ast_play_and_wait(chan, "vm-messages");
06675                if (!res)
06676                   res = ast_play_and_wait(chan, "vm-INBOX");
06677             }
06678          }
06679          if (vms->oldmessages && !res)
06680             res = ast_play_and_wait(chan, "vm-and");
06681       }
06682       if (!res && vms->oldmessages) {
06683          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06684          if (!res) {
06685             if (vms->oldmessages == 1) {
06686                res = ast_play_and_wait(chan, "vm-message");
06687                if (!res)
06688                   res = ast_play_and_wait(chan, "vm-Olds");
06689             } else {
06690                res = ast_play_and_wait(chan, "vm-messages");
06691                if (!res)
06692                   res = ast_play_and_wait(chan, "vm-Old");
06693             }
06694          }
06695       }
06696       if (!res) {
06697          if (!vms->oldmessages && !vms->newmessages) {
06698             res = ast_play_and_wait(chan, "vm-no");
06699             if (!res)
06700                res = ast_play_and_wait(chan, "vm-messages");
06701          }
06702       }
06703    }
06704    return res;
06705 }

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

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

06518                                                                          {
06519    /* Introduce messages they have */
06520    int res;
06521    if (!vms->oldmessages && !vms->newmessages) {
06522       res = ast_play_and_wait(chan, "vm-nomessages");
06523       return res;
06524    }
06525    else {
06526       res = ast_play_and_wait(chan, "vm-youhave");
06527    }
06528    if (vms->newmessages) {
06529       if (!res)
06530          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06531       if ((vms->newmessages == 1)) {
06532          if (!res)
06533             res = ast_play_and_wait(chan, "vm-message");
06534          if (!res)
06535             res = ast_play_and_wait(chan, "vm-INBOXs");
06536       }
06537       else {
06538          if (!res)
06539             res = ast_play_and_wait(chan, "vm-messages");
06540          if (!res)
06541             res = ast_play_and_wait(chan, "vm-INBOX");
06542       }
06543       if (vms->oldmessages && !res)
06544          res = ast_play_and_wait(chan, "vm-and");
06545    }
06546    if (vms->oldmessages) {
06547       if (!res)
06548          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06549       if (vms->oldmessages == 1) {
06550          if (!res)
06551             res = ast_play_and_wait(chan, "vm-message");
06552          if (!res)
06553             res = ast_play_and_wait(chan, "vm-Olds");
06554       }
06555       else {
06556          if (!res)
06557       res = ast_play_and_wait(chan, "vm-messages");
06558          if (!res)
06559             res = ast_play_and_wait(chan, "vm-Old");
06560       }
06561    }
06562    return res;
06563 }

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

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

06329 {
06330    /* Introduce messages they have */
06331    int res;
06332 
06333    res = ast_play_and_wait(chan, "vm-youhave");
06334    if (res)
06335       return res;
06336 
06337    if (!vms->oldmessages && !vms->newmessages) {
06338       res = ast_play_and_wait(chan, "vm-no");
06339       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06340       return res;
06341    }
06342 
06343    if (vms->newmessages) {
06344       if ((vms->newmessages == 1)) {
06345          res = ast_play_and_wait(chan, "digits/ett");
06346          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
06347          res = res ? res : ast_play_and_wait(chan, "vm-message");
06348       } else {
06349          res = say_and_wait(chan, vms->newmessages, chan->language);
06350          res = res ? res : ast_play_and_wait(chan, "vm-nya");
06351          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06352       }
06353       if (!res && vms->oldmessages)
06354          res = ast_play_and_wait(chan, "vm-and");
06355    }
06356    if (!res && vms->oldmessages) {
06357       if (vms->oldmessages == 1) {
06358          res = ast_play_and_wait(chan, "digits/ett");
06359          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
06360          res = res ? res : ast_play_and_wait(chan, "vm-message");
06361       } else {
06362          res = say_and_wait(chan, vms->oldmessages, chan->language);
06363          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
06364          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06365       }
06366    }
06367 
06368    return res;
06369 }

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

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

02222 {
02223    switch (ast_lock_path(path)) {
02224    case AST_LOCK_TIMEOUT:
02225       return -1;
02226    default:
02227       return 0;
02228    }
02229 }

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

Definition at line 945 of file app_voicemail.c.

References VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

00946 {
00947    FILE *p = NULL;
00948    int pfd = mkstemp(template);
00949    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
00950    if (pfd > -1) {
00951       p = fdopen(pfd, "w+");
00952       if (!p) {
00953          close(pfd);
00954          pfd = -1;
00955       }
00956    }
00957    return p;
00958 }

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

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

Referenced by vm_execmain().

06890 {
06891    int cmd = 0;
06892    int duration = 0;
06893    int tries = 0;
06894    char newpassword[80] = "";
06895    char newpassword2[80] = "";
06896    char prefile[PATH_MAX] = "";
06897    unsigned char buf[256];
06898    int bytes=0;
06899 
06900    if (ast_adsi_available(chan)) {
06901       bytes += adsi_logo(buf + bytes);
06902       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
06903       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06904       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06905       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06906       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06907    }
06908 
06909    /* First, have the user change their password 
06910       so they won't get here again */
06911    for (;;) {
06912       newpassword[1] = '\0';
06913       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06914       if (cmd == '#')
06915          newpassword[0] = '\0';
06916       if (cmd < 0 || cmd == 't' || cmd == '#')
06917          return cmd;
06918       cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
06919       if (cmd < 0 || cmd == 't' || cmd == '#')
06920          return cmd;
06921       newpassword2[1] = '\0';
06922       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06923       if (cmd == '#')
06924          newpassword2[0] = '\0';
06925       if (cmd < 0 || cmd == 't' || cmd == '#')
06926          return cmd;
06927       cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
06928       if (cmd < 0 || cmd == 't' || cmd == '#')
06929          return cmd;
06930       if (!strcmp(newpassword, newpassword2))
06931          break;
06932       ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
06933       cmd = ast_play_and_wait(chan, "vm-mismatch");
06934       if (++tries == 3)
06935          return -1;
06936       if (cmd == 0) {
06937          cmd = ast_play_and_wait(chan, "vm-pls-try-again");
06938       }
06939    }
06940    if (ast_strlen_zero(ext_pass_cmd)) 
06941       vm_change_password(vmu,newpassword);
06942    else 
06943       vm_change_password_shell(vmu,newpassword);
06944    if (option_debug > 2)
06945       ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
06946    cmd = ast_play_and_wait(chan,"vm-passchanged");
06947 
06948    /* If forcename is set, have the user record their name */  
06949    if (ast_test_flag(vmu, VM_FORCENAME)) {
06950       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06951       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06952          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06953          if (cmd < 0 || cmd == 't' || cmd == '#')
06954             return cmd;
06955       }
06956    }
06957 
06958    /* If forcegreetings is set, have the user record their greetings */
06959    if (ast_test_flag(vmu, VM_FORCEGREET)) {
06960       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06961       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06962          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06963          if (cmd < 0 || cmd == 't' || cmd == '#')
06964             return cmd;
06965       }
06966 
06967       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06968       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06969          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06970          if (cmd < 0 || cmd == 't' || cmd == '#')
06971             return cmd;
06972       }
06973    }
06974 
06975    return cmd;
06976 }

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

Definition at line 6978 of file app_voicemail.c.

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

Referenced by vm_execmain().

06979 {
06980    int cmd = 0;
06981    int retries = 0;
06982    int duration = 0;
06983    char newpassword[80] = "";
06984    char newpassword2[80] = "";
06985    char prefile[PATH_MAX] = "";
06986    unsigned char buf[256];
06987    int bytes=0;
06988 
06989    if (ast_adsi_available(chan))
06990    {
06991       bytes += adsi_logo(buf + bytes);
06992       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
06993       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06994       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06995       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06996       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06997    }
06998    while ((cmd >= 0) && (cmd != 't')) {
06999       if (cmd)
07000          retries = 0;
07001       switch (cmd) {
07002       case '1':
07003          snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
07004          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07005          break;
07006       case '2': 
07007          snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
07008          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07009          break;
07010       case '3': 
07011          snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
07012          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07013          break;
07014       case '4': 
07015          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
07016          break;
07017       case '5':
07018          if (vmu->password[0] == '-') {
07019             cmd = ast_play_and_wait(chan, "vm-no");
07020             break;
07021          }
07022          newpassword[1] = '\0';
07023          newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
07024          if (cmd == '#')
07025             newpassword[0] = '\0';
07026          else {
07027             if (cmd < 0)
07028                break;
07029             if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
07030                break;
07031             }
07032          }
07033          newpassword2[1] = '\0';
07034          newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
07035          if (cmd == '#')
07036             newpassword2[0] = '\0';
07037          else {
07038             if (cmd < 0)
07039                break;
07040 
07041             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#")) < 0) {
07042                break;
07043             }
07044          }
07045          if (strcmp(newpassword, newpassword2)) {
07046             ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
07047             cmd = ast_play_and_wait(chan, "vm-mismatch");
07048             if (!cmd) {
07049                cmd = ast_play_and_wait(chan, "vm-pls-try-again");
07050             }
07051             break;
07052          }
07053          if (ast_strlen_zero(ext_pass_cmd)) 
07054             vm_change_password(vmu,newpassword);
07055          else 
07056             vm_change_password_shell(vmu,newpassword);
07057          if (option_debug > 2)
07058             ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
07059          cmd = ast_play_and_wait(chan,"vm-passchanged");
07060          break;
07061       case '*': 
07062          cmd = 't';
07063          break;
07064       default: 
07065          cmd = 0;
07066          snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
07067          RETRIEVE(prefile, -1, vmu);
07068          if (ast_fileexists(prefile, NULL, NULL))
07069             cmd = ast_play_and_wait(chan, "vm-tmpexists");
07070          DISPOSE(prefile, -1);
07071          if (!cmd)
07072             cmd = ast_play_and_wait(chan, "vm-options");
07073          if (!cmd)
07074             cmd = ast_waitfordigit(chan,6000);
07075          if (!cmd)
07076             retries++;
07077          if (retries > 3)
07078             cmd = 't';
07079       }
07080    }
07081    if (cmd == 't')
07082       cmd = 0;
07083    return cmd;
07084 }

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

Definition at line 5940 of file app_voicemail.c.

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

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

05941 {
05942    int cmd;
05943 
05944    if (  !strncasecmp(chan->language, "it", 2) ||
05945         !strncasecmp(chan->language, "es", 2) ||
05946         !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */
05947       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
05948       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05949    } else if (!strncasecmp(chan->language, "gr", 2)) {
05950       return vm_play_folder_name_gr(chan, mbox);
05951    } else if (!strncasecmp(chan->language, "pl", 2)) {
05952       return vm_play_folder_name_pl(chan, mbox);
05953    } else if (!strncasecmp(chan->language, "ua", 2)) {  /* Ukrainian syntax */
05954       return vm_play_folder_name_ua(chan, mbox);
05955    } else if (!strncasecmp(chan->language, "he", 2)) {  /* Hebrew syntax */
05956       cmd = ast_play_and_wait(chan, mbox);
05957       return cmd;
05958    } else {  /* Default English */
05959       cmd = ast_play_and_wait(chan, mbox);
05960       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
05961    }
05962 }

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

Definition at line 5893 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05894 {
05895    int cmd;
05896    char *buf;
05897 
05898    buf = alloca(strlen(mbox)+2); 
05899    strcpy(buf, mbox);
05900    strcat(buf,"s");
05901 
05902    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
05903       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
05904       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
05905    } else {
05906       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
05907       return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
05908    }
05909 }

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

Definition at line 5911 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05912 {
05913    int cmd;
05914 
05915    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
05916       if (!strcasecmp(mbox, "vm-INBOX"))
05917          cmd = ast_play_and_wait(chan, "vm-new-e");
05918       else
05919          cmd = ast_play_and_wait(chan, "vm-old-e");
05920       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05921    } else {
05922       cmd = ast_play_and_wait(chan, "vm-messages");
05923       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05924    }
05925 }

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

Definition at line 5927 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05928 {
05929    int cmd;
05930 
05931    if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")){
05932       cmd = ast_play_and_wait(chan, "vm-messages");
05933       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05934    } else {
05935       cmd = ast_play_and_wait(chan, mbox);
05936       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05937    }
05938 }

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

Definition at line 7086 of file app_voicemail.c.

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

Referenced by vm_options().

07087 {
07088    int res;
07089    int cmd = 0;
07090    int retries = 0;
07091    int duration = 0;
07092    char prefile[PATH_MAX] = "";
07093    unsigned char buf[256];
07094    char dest[PATH_MAX];
07095    int bytes = 0;
07096 
07097    if (ast_adsi_available(chan)) {
07098       bytes += adsi_logo(buf + bytes);
07099       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
07100       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
07101       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
07102       bytes += ast_adsi_voice_mode(buf + bytes, 0);
07103       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
07104    }
07105 
07106    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
07107    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
07108       ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
07109       return -1;
07110    }
07111    while ((cmd >= 0) && (cmd != 't')) {
07112       if (cmd)
07113          retries = 0;
07114       RETRIEVE(prefile, -1, vmu);
07115       if (ast_fileexists(prefile, NULL, NULL) <= 0) {
07116          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07117          cmd = 't';  
07118       } else {
07119          switch (cmd) {
07120          case '1':
07121             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07122             break;
07123          case '2':
07124             DELETE(prefile, -1, prefile, vmu);
07125             ast_play_and_wait(chan, "vm-tempremoved");
07126             cmd = 't';  
07127             break;
07128          case '*': 
07129             cmd = 't';
07130             break;
07131          default:
07132             cmd = ast_play_and_wait(chan,
07133                ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
07134                   "vm-tempgreeting2" : "vm-tempgreeting");
07135             if (!cmd)
07136                cmd = ast_waitfordigit(chan,6000);
07137             if (!cmd)
07138                retries++;
07139             if (retries > 3)
07140                cmd = 't';
07141          }
07142       }
07143       DISPOSE(prefile, -1);
07144    }
07145    if (cmd == 't')
07146       cmd = 0;
07147    return cmd;
07148 }

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

Definition at line 8109 of file app_voicemail.c.

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

Referenced by load_module().

08110 {
08111    struct ast_module_user *u;
08112    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
08113    struct ast_vm_user vmus;
08114    char *options = NULL;
08115    int silent = 0, skipuser = 0;
08116    int res = -1;
08117 
08118    u = ast_module_user_add(chan);
08119    
08120    if (s) {
08121       s = ast_strdupa(s);
08122       user = strsep(&s, "|");
08123       options = strsep(&s, "|");
08124       if (user) {
08125          s = user;
08126          user = strsep(&s, "@");
08127          context = strsep(&s, "");
08128          if (!ast_strlen_zero(user))
08129             skipuser++;
08130          ast_copy_string(mailbox, user, sizeof(mailbox));
08131       }
08132    }
08133 
08134    if (options) {
08135       silent = (strchr(options, 's')) != NULL;
08136    }
08137 
08138    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
08139       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
08140       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
08141       ast_play_and_wait(chan, "auth-thankyou");
08142       res = 0;
08143    }
08144 
08145    ast_module_user_remove(u);
08146    return res;
08147 }

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

Definition at line 3098 of file app_voicemail.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_strlen_zero(), ast_vm_user::list, vm_zone::name, vm_zone::timezone, and ast_vm_user::zonetag.

Referenced by make_email_file(), and sendpage().

03099 {
03100    const struct vm_zone *z = NULL;
03101    time_t t = time(NULL);
03102 
03103    /* Does this user have a timezone specified? */
03104    if (!ast_strlen_zero(vmu->zonetag)) {
03105       /* Find the zone in the list */
03106       AST_LIST_LOCK(&zones);
03107       AST_LIST_TRAVERSE(&zones, z, list) {
03108          if (!strcmp(z->name, vmu->zonetag))
03109             break;
03110       }
03111       AST_LIST_UNLOCK(&zones);
03112    }
03113    ast_localtime(&t, tm, z ? z->timezone : NULL);
03114    return tm;
03115 }

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

Definition at line 5430 of file app_voicemail.c.

References ast_control_streamfile().

05431 {
05432    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
05433 }

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

Definition at line 5422 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_log(), ast_stream_and_wait(), and ast_channel::language.

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

05423 {
05424    int res;
05425    if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0) 
05426       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
05427    return res;
05428 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 9405 of file app_voicemail.c.

char* addesc = "Comedian Mail" [static]

Definition at line 459 of file app_voicemail.c.

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

Definition at line 583 of file app_voicemail.c.

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

Definition at line 584 of file app_voicemail.c.

int adsiver = 1 [static]

Definition at line 585 of file app_voicemail.c.

char* app = "VoiceMail" [static]

Definition at line 535 of file app_voicemail.c.

char* app2 = "VoiceMailMain" [static]

Definition at line 538 of file app_voicemail.c.

char* app3 = "MailboxExists" [static]

Definition at line 540 of file app_voicemail.c.

char* app4 = "VMAuthenticate" [static]

Definition at line 541 of file app_voicemail.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 9405 of file app_voicemail.c.

char callcontext[AST_MAX_CONTEXT] [static]

Definition at line 568 of file app_voicemail.c.

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

Definition at line 581 of file app_voicemail.c.

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static]

Definition at line 571 of file app_voicemail.c.

struct ast_cli_entry cli_show_voicemail_users_deprecated [static]

Initial value:

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

Definition at line 8251 of file app_voicemail.c.

struct ast_cli_entry cli_show_voicemail_zones_deprecated [static]

Initial value:

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

Definition at line 8256 of file app_voicemail.c.

struct ast_cli_entry cli_voicemail[] [static]

Definition at line 8261 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char* descrip_vm [static]

Definition at line 464 of file app_voicemail.c.

char* descrip_vm_box_exists [static]

Definition at line 510 of file app_voicemail.c.

char* descrip_vmain [static]

Definition at line 492 of file app_voicemail.c.

char* descrip_vmauthenticate [static]

Definition at line 524 of file app_voicemail.c.

char dialcontext[AST_MAX_CONTEXT] [static]

Definition at line 567 of file app_voicemail.c.

Referenced by directory_exec().

char* emailbody = NULL [static]

Definition at line 574 of file app_voicemail.c.

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

Definition at line 586 of file app_voicemail.c.

char* emailsubject = NULL [static]

Definition at line 575 of file app_voicemail.c.

char emailtitle[100] [static]

Definition at line 580 of file app_voicemail.c.

char exitcontext[AST_MAX_CONTEXT] [static]

Definition at line 569 of file app_voicemail.c.

Referenced by conf_run().

char ext_pass_cmd[128] [static]

Definition at line 445 of file app_voicemail.c.

char externnotify[160] [static]

Definition at line 553 of file app_voicemail.c.

char fromstring[100] [static]

Definition at line 578 of file app_voicemail.c.

struct ast_flags globalflags = {0} [static]

Definition at line 563 of file app_voicemail.c.

char mailcmd[160] [static]

Definition at line 550 of file app_voicemail.c.

int maxgreet [static]

Definition at line 559 of file app_voicemail.c.

int maxlogins [static]

Definition at line 561 of file app_voicemail.c.

int maxmsg [static]

Definition at line 547 of file app_voicemail.c.

int maxsilence [static]

Definition at line 546 of file app_voicemail.c.

Referenced by ast_record_review().

int my_umask [static]

Definition at line 447 of file app_voicemail.c.

char* pagerbody = NULL [static]

Definition at line 576 of file app_voicemail.c.

char pagerfromstring[100] [static]

Definition at line 579 of file app_voicemail.c.

char* pagersubject = NULL [static]

Definition at line 577 of file app_voicemail.c.

char preprocesscmd[160] [static]

Definition at line 551 of file app_voicemail.c.

char preprocessfmt[20] [static]

Definition at line 552 of file app_voicemail.c.

int saydurationminfo [static]

Definition at line 565 of file app_voicemail.c.

char serveremail[80] [static]

Definition at line 549 of file app_voicemail.c.

int silencethreshold = 128 [static]

Definition at line 548 of file app_voicemail.c.

int skipms [static]

Definition at line 560 of file app_voicemail.c.

Referenced by controlplayback_exec(), and handle_controlstreamfile().

struct ast_smdi_interface* smdi_iface = NULL [static]

Definition at line 554 of file app_voicemail.c.

Referenced by load_config(), and run_externnotify().

char* synopsis_vm [static]

Initial value:

"Leave a Voicemail message"

Definition at line 461 of file app_voicemail.c.

char* synopsis_vm_box_exists [static]

Initial value:

"Check to see if Voicemail mailbox exists"

Definition at line 507 of file app_voicemail.c.

char* synopsis_vmain [static]

Initial value:

"Check Voicemail messages"

Definition at line 489 of file app_voicemail.c.

char* synopsis_vmauthenticate [static]

Initial value:

"Authenticate with Voicemail passwords"

Definition at line 521 of file app_voicemail.c.

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

Definition at line 457 of file app_voicemail.c.

Referenced by pbx_load_users().

struct ast_app_option vm_app_options[128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'j' ] = { .flag = OPT_PRIORITY_JUMP }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 },} [static]

Definition at line 237 of file app_voicemail.c.

Referenced by vm_exec(), and vm_execmain().

enum { ... } vm_option_args

enum { ... } vm_option_flags

char VM_SPOOL_DIR[PATH_MAX] [static]

Definition at line 443 of file app_voicemail.c.

char vmfmts[80] [static]

Definition at line 555 of file app_voicemail.c.

int vmmaxmessage [static]

Definition at line 558 of file app_voicemail.c.

int vmminmessage [static]

Definition at line 557 of file app_voicemail.c.

char voicemail_show_users_help[] [static]

Initial value:

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

Definition at line 8149 of file app_voicemail.c.

char voicemail_show_zones_help[] [static]

Initial value:

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

Definition at line 8153 of file app_voicemail.c.

double volgain [static]

Definition at line 556 of file app_voicemail.c.

char zonetag[80] [static]

Definition at line 545 of file app_voicemail.c.

Referenced by build_peer().


Generated on Thu Mar 25 10:39:20 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7