Thu Oct 8 00:59:18 2009

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 (const char *input, char *buf, size_t buflen)
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_cz (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_de (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_en (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_es (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_fr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_gr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_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 = "6989f2ec67f8497e38c12890500c525b" , .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 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 168 of file app_voicemail.c.

Referenced by load_config().

#define BASELINELEN   72

Definition at line 184 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 185 of file app_voicemail.c.

#define BASEMAXINLINE   256

Definition at line 185 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 165 of file app_voicemail.c.

#define COMMAND_TIMEOUT   5000

Definition at line 161 of file app_voicemail.c.

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

Definition at line 433 of file app_voicemail.c.

Referenced by copy_message().

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

Definition at line 434 of file app_voicemail.c.

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

#define DISPOSE ( a,
 ) 

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

Referenced by base_encode(), and ochar().

#define ERROR_LOCK_PATH   -100

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

Referenced by save_to_folder().

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

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

Referenced by leave_voicemail(), and play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 188 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 189 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 176 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

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

Referenced by close_mailbox(), and resequence_mailbox().

#define RETRIEVE ( a,
b,
 ) 

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

Referenced by load_config().

#define SMDI_MWI_WAIT_TIMEOUT   1000

Definition at line 159 of file app_voicemail.c.

Referenced by run_externnotify().

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

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

#define VM_ALLOCED   (1 << 13)

Definition at line 204 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 202 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 203 of file app_voicemail.c.

Referenced by apply_option(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 201 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

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

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

#define VM_OPERATOR   (1 << 1)

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

Referenced by load_config(), and make_email_file().

#define VM_REVIEW   (1 << 0)

Definition at line 191 of file app_voicemail.c.

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

#define VM_SAYCID   (1 << 2)

Definition at line 193 of file app_voicemail.c.

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

#define VM_SAYDURATION   (1 << 5)

Definition at line 196 of file app_voicemail.c.

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

#define VM_SEARCH   (1 << 14)

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

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

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

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

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 167 of file app_voicemail.c.

#define VOICEMAIL_DIR_MODE   0777

Definition at line 163 of file app_voicemail.c.

Referenced by create_dirpath().

#define VOICEMAIL_FILE_MODE   0666

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

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

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_ARRAY_SIZE 

Definition at line 221 of file app_voicemail.c.

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


Function Documentation

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

Definition at line 3820 of file app_voicemail.c.

References ast_strlen_zero().

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

03821 {
03822    DIR *dir;
03823    struct dirent *de;
03824    char fn[256];
03825    int ret = 0;
03826    if (!folder)
03827       folder = "INBOX";
03828    /* If no mailbox, return immediately */
03829    if (ast_strlen_zero(mailbox))
03830       return 0;
03831    if (!context)
03832       context = "default";
03833    snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
03834    dir = opendir(fn);
03835    if (!dir)
03836       return 0;
03837    while ((de = readdir(dir))) {
03838       if (!strncasecmp(de->d_name, "msg", 3)) {
03839          if (shortcircuit) {
03840             ret = 1;
03841             break;
03842          } else if (!strncasecmp(de->d_name + 8, "txt", 3))
03843             ret++;
03844       }
03845    }
03846    closedir(dir);
03847    return ret;
03848 }

static void __reg_module ( void   )  [static]

Definition at line 9318 of file app_voicemail.c.

static void __unreg_module ( void   )  [static]

Definition at line 9318 of file app_voicemail.c.

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

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

04580 {
04581    int x;
04582    if (!ast_adsi_available(chan))
04583       return;
04584    x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
04585    if (x < 0)
04586       return;
04587    if (!x) {
04588       if (adsi_load_vmail(chan, useadsi)) {
04589          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
04590          return;
04591       }
04592    } else
04593       *useadsi = 1;
04594 }

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

Definition at line 4768 of file app_voicemail.c.

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

Referenced by vm_execmain().

04769 {
04770    int bytes=0;
04771    unsigned char buf[256];
04772    unsigned char keys[8];
04773 
04774    int x;
04775 
04776    if (!ast_adsi_available(chan))
04777       return;
04778 
04779    /* New meaning for keys */
04780    for (x=0;x<5;x++)
04781       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
04782 
04783    keys[6] = 0x0;
04784    keys[7] = 0x0;
04785 
04786    if (!vms->curmsg) {
04787       /* No prev key, provide "Folder" instead */
04788       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04789    }
04790    if (vms->curmsg >= vms->lastmsg) {
04791       /* If last message ... */
04792       if (vms->curmsg) {
04793          /* but not only message, provide "Folder" instead */
04794          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04795       } else {
04796          /* Otherwise if only message, leave blank */
04797          keys[3] = 1;
04798       }
04799    }
04800 
04801    /* If deleted, show "undeleted" */
04802    if (vms->deleted[vms->curmsg]) 
04803       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
04804 
04805    /* Except "Exit" */
04806    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
04807    bytes += ast_adsi_set_keys(buf + bytes, keys);
04808    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04809 
04810    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04811 }

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

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

04645 {
04646    unsigned char buf[256];
04647    int bytes=0;
04648    unsigned char keys[8];
04649    int x,y;
04650 
04651    if (!ast_adsi_available(chan))
04652       return;
04653 
04654    for (x=0;x<5;x++) {
04655       y = ADSI_KEY_APPS + 12 + start + x;
04656       if (y > ADSI_KEY_APPS + 12 + 4)
04657          y = 0;
04658       keys[x] = ADSI_KEY_SKT | y;
04659    }
04660    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
04661    keys[6] = 0;
04662    keys[7] = 0;
04663 
04664    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
04665    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
04666    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04667    bytes += ast_adsi_set_keys(buf + bytes, keys);
04668    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04669 
04670    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04671 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

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

04917 {
04918    unsigned char buf[256];
04919    int bytes=0;
04920 
04921    if (!ast_adsi_available(chan))
04922       return;
04923    bytes += adsi_logo(buf + bytes);
04924    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
04925    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
04926    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04927    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04928 
04929    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04930 }

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

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

04449 {
04450    unsigned char buf[256];
04451    int bytes=0;
04452    int x;
04453    char num[5];
04454 
04455    *useadsi = 0;
04456    bytes += ast_adsi_data_mode(buf + bytes);
04457    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04458 
04459    bytes = 0;
04460    bytes += adsi_logo(buf);
04461    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04462 #ifdef DISPLAY
04463    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
04464 #endif
04465    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04466    bytes += ast_adsi_data_mode(buf + bytes);
04467    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04468 
04469    if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
04470       bytes = 0;
04471       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
04472       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04473       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04474       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04475       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04476       return 0;
04477    }
04478 
04479 #ifdef DISPLAY
04480    /* Add a dot */
04481    bytes = 0;
04482    bytes += ast_adsi_logo(buf);
04483    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04484    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
04485    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04486    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04487 #endif
04488    bytes = 0;
04489    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
04490    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
04491    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
04492    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
04493    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
04494    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
04495    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04496 
04497 #ifdef DISPLAY
04498    /* Add another dot */
04499    bytes = 0;
04500    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
04501    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04502 
04503    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04504    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04505 #endif
04506 
04507    bytes = 0;
04508    /* These buttons we load but don't use yet */
04509    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
04510    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
04511    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
04512    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
04513    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
04514    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
04515    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04516 
04517 #ifdef DISPLAY
04518    /* Add another dot */
04519    bytes = 0;
04520    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
04521    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04522    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04523 #endif
04524 
04525    bytes = 0;
04526    for (x=0;x<5;x++) {
04527       snprintf(num, sizeof(num), "%d", x);
04528       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
04529    }
04530    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
04531    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04532 
04533 #ifdef DISPLAY
04534    /* Add another dot */
04535    bytes = 0;
04536    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
04537    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04538    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04539 #endif
04540 
04541    if (ast_adsi_end_download(chan)) {
04542       bytes = 0;
04543       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
04544       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04545       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04546       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04547       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04548       return 0;
04549    }
04550    bytes = 0;
04551    bytes += ast_adsi_download_disconnect(buf + bytes);
04552    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04553    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04554 
04555    if (option_debug)
04556       ast_log(LOG_DEBUG, "Done downloading scripts...\n");
04557 
04558 #ifdef DISPLAY
04559    /* Add last dot */
04560    bytes = 0;
04561    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
04562    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04563 #endif
04564    if (option_debug)
04565       ast_log(LOG_DEBUG, "Restarting session...\n");
04566 
04567    bytes = 0;
04568    /* Load the session now */
04569    if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
04570       *useadsi = 1;
04571       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
04572    } else
04573       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
04574 
04575    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04576    return 0;
04577 }

static void adsi_login ( struct ast_channel chan  )  [static]

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

04597 {
04598    unsigned char buf[256];
04599    int bytes=0;
04600    unsigned char keys[8];
04601    int x;
04602    if (!ast_adsi_available(chan))
04603       return;
04604 
04605    for (x=0;x<8;x++)
04606       keys[x] = 0;
04607    /* Set one key for next */
04608    keys[3] = ADSI_KEY_APPS + 3;
04609 
04610    bytes += adsi_logo(buf + bytes);
04611    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
04612    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
04613    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04614    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
04615    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
04616    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
04617    bytes += ast_adsi_set_keys(buf + bytes, keys);
04618    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04619    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04620 }

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

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

04441 {
04442    int bytes = 0;
04443    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
04444    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
04445    return bytes;
04446 }

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

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

04674 {
04675    int bytes=0;
04676    unsigned char buf[256]; 
04677    char buf1[256], buf2[256];
04678    char fn2[PATH_MAX];
04679 
04680    char cid[256]="";
04681    char *val;
04682    char *name, *num;
04683    char datetime[21]="";
04684    FILE *f;
04685 
04686    unsigned char keys[8];
04687 
04688    int x;
04689 
04690    if (!ast_adsi_available(chan))
04691       return;
04692 
04693    /* Retrieve important info */
04694    snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
04695    f = fopen(fn2, "r");
04696    if (f) {
04697       while (!feof(f)) {   
04698          if (!fgets((char *)buf, sizeof(buf), f)) {
04699             continue;
04700          }
04701          if (!feof(f)) {
04702             char *stringp=NULL;
04703             stringp = (char *)buf;
04704             strsep(&stringp, "=");
04705             val = strsep(&stringp, "=");
04706             if (!ast_strlen_zero(val)) {
04707                if (!strcmp((char *)buf, "callerid"))
04708                   ast_copy_string(cid, val, sizeof(cid));
04709                if (!strcmp((char *)buf, "origdate"))
04710                   ast_copy_string(datetime, val, sizeof(datetime));
04711             }
04712          }
04713       }
04714       fclose(f);
04715    }
04716    /* New meaning for keys */
04717    for (x=0;x<5;x++)
04718       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
04719    keys[6] = 0x0;
04720    keys[7] = 0x0;
04721 
04722    if (!vms->curmsg) {
04723       /* No prev key, provide "Folder" instead */
04724       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04725    }
04726    if (vms->curmsg >= vms->lastmsg) {
04727       /* If last message ... */
04728       if (vms->curmsg) {
04729          /* but not only message, provide "Folder" instead */
04730          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04731          bytes += ast_adsi_voice_mode(buf + bytes, 0);
04732 
04733       } else {
04734          /* Otherwise if only message, leave blank */
04735          keys[3] = 1;
04736       }
04737    }
04738 
04739    if (!ast_strlen_zero(cid)) {
04740       ast_callerid_parse(cid, &name, &num);
04741       if (!name)
04742          name = num;
04743    } else
04744       name = "Unknown Caller";
04745 
04746    /* If deleted, show "undeleted" */
04747 
04748    if (vms->deleted[vms->curmsg])
04749       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
04750 
04751    /* Except "Exit" */
04752    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
04753    snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
04754       strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
04755    snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
04756 
04757    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04758    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04759    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
04760    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
04761    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04762    bytes += ast_adsi_set_keys(buf + bytes, keys);
04763    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04764 
04765    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04766 }

static void adsi_password ( struct ast_channel chan  )  [static]

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

04623 {
04624    unsigned char buf[256];
04625    int bytes=0;
04626    unsigned char keys[8];
04627    int x;
04628    if (!ast_adsi_available(chan))
04629       return;
04630 
04631    for (x=0;x<8;x++)
04632       keys[x] = 0;
04633    /* Set one key for next */
04634    keys[3] = ADSI_KEY_APPS + 3;
04635 
04636    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04637    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
04638    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
04639    bytes += ast_adsi_set_keys(buf + bytes, keys);
04640    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04641    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04642 }

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

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

04814 {
04815    unsigned char buf[256] = "";
04816    char buf1[256] = "", buf2[256] = "";
04817    int bytes=0;
04818    unsigned char keys[8];
04819    int x;
04820 
04821    char *newm = (vms->newmessages == 1) ? "message" : "messages";
04822    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
04823    if (!ast_adsi_available(chan))
04824       return;
04825    if (vms->newmessages) {
04826       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
04827       if (vms->oldmessages) {
04828          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
04829          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
04830       } else {
04831          snprintf(buf2, sizeof(buf2), "%s.", newm);
04832       }
04833    } else if (vms->oldmessages) {
04834       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
04835       snprintf(buf2, sizeof(buf2), "%s.", oldm);
04836    } else {
04837       strcpy(buf1, "You have no messages.");
04838       buf2[0] = ' ';
04839       buf2[1] = '\0';
04840    }
04841    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04842    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04843    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04844 
04845    for (x=0;x<6;x++)
04846       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
04847    keys[6] = 0;
04848    keys[7] = 0;
04849 
04850    /* Don't let them listen if there are none */
04851    if (vms->lastmsg < 0)
04852       keys[0] = 1;
04853    bytes += ast_adsi_set_keys(buf + bytes, keys);
04854 
04855    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04856 
04857    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04858 }

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

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

04861 {
04862    unsigned char buf[256] = "";
04863    char buf1[256] = "", buf2[256] = "";
04864    int bytes=0;
04865    unsigned char keys[8];
04866    int x;
04867 
04868    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
04869 
04870    if (!ast_adsi_available(chan))
04871       return;
04872 
04873    /* Original command keys */
04874    for (x=0;x<6;x++)
04875       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
04876 
04877    keys[6] = 0;
04878    keys[7] = 0;
04879 
04880    if ((vms->lastmsg + 1) < 1)
04881       keys[0] = 0;
04882 
04883    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
04884       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
04885 
04886    if (vms->lastmsg + 1)
04887       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
04888    else
04889       strcpy(buf2, "no messages.");
04890    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04891    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04892    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
04893    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04894    bytes += ast_adsi_set_keys(buf + bytes, keys);
04895 
04896    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04897 
04898    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04899    
04900 }

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 8915 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().

08916 {
08917    int res = 0;
08918    char filename[PATH_MAX];
08919    struct ast_config *msg_cfg = NULL;
08920    const char *origtime, *context;
08921    char *cid, *name, *num;
08922    int retries = 0;
08923 
08924    vms->starting = 0; 
08925    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08926 
08927    /* Retrieve info from VM attribute file */
08928    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
08929    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
08930    RETRIEVE(vms->curdir, vms->curmsg, vmu);
08931    msg_cfg = ast_config_load(filename);
08932    DISPOSE(vms->curdir, vms->curmsg);
08933    if (!msg_cfg) {
08934       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
08935       return 0;
08936    }
08937 
08938    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
08939       ast_config_destroy(msg_cfg);
08940       return 0;
08941    }
08942 
08943    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
08944 
08945    context = ast_variable_retrieve(msg_cfg, "message", "context");
08946    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
08947       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
08948    switch (option) {
08949    case 3:
08950       if (!res)
08951          res = play_message_datetime(chan, vmu, origtime, filename);
08952       if (!res)
08953          res = play_message_callerid(chan, vms, cid, context, 0);
08954 
08955       res = 't';
08956       break;
08957 
08958    case 2:  /* Call back */
08959 
08960       if (ast_strlen_zero(cid))
08961          break;
08962 
08963       ast_callerid_parse(cid, &name, &num);
08964       while ((res > -1) && (res != 't')) {
08965          switch (res) {
08966          case '1':
08967             if (num) {
08968                /* Dial the CID number */
08969                res = dialout(chan, vmu, num, vmu->callback);
08970                if (res) {
08971                   ast_config_destroy(msg_cfg);
08972                   return 9;
08973                }
08974             } else {
08975                res = '2';
08976             }
08977             break;
08978 
08979          case '2':
08980             /* Want to enter a different number, can only do this if there's a dialout context for this user */
08981             if (!ast_strlen_zero(vmu->dialout)) {
08982                res = dialout(chan, vmu, NULL, vmu->dialout);
08983                if (res) {
08984                   ast_config_destroy(msg_cfg);
08985                   return 9;
08986                }
08987             } else {
08988                if (option_verbose > 2)
08989                   ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
08990                res = ast_play_and_wait(chan, "vm-sorry");
08991             }
08992             ast_config_destroy(msg_cfg);
08993             return res;
08994          case '*':
08995             res = 't';
08996             break;
08997          case '3':
08998          case '4':
08999          case '5':
09000          case '6':
09001          case '7':
09002          case '8':
09003          case '9':
09004          case '0':
09005 
09006             res = ast_play_and_wait(chan, "vm-sorry");
09007             retries++;
09008             break;
09009          default:
09010             if (num) {
09011                if (option_verbose > 2)
09012                   ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
09013                res = ast_play_and_wait(chan, "vm-num-i-have");
09014                if (!res)
09015                   res = play_message_callerid(chan, vms, num, vmu->context, 1);
09016                if (!res)
09017                   res = ast_play_and_wait(chan, "vm-tocallnum");
09018                /* Only prompt for a caller-specified number if there is a dialout context specified */
09019                if (!ast_strlen_zero(vmu->dialout)) {
09020                   if (!res)
09021                      res = ast_play_and_wait(chan, "vm-calldiffnum");
09022                }
09023             } else {
09024                res = ast_play_and_wait(chan, "vm-nonumber");
09025                if (!ast_strlen_zero(vmu->dialout)) {
09026                   if (!res)
09027                      res = ast_play_and_wait(chan, "vm-toenternumber");
09028                }
09029             }
09030             if (!res)
09031                res = ast_play_and_wait(chan, "vm-star-cancel");
09032             if (!res)
09033                res = ast_waitfordigit(chan, 6000);
09034             if (!res) {
09035                retries++;
09036                if (retries > 3)
09037                   res = 't';
09038             }
09039             break; 
09040             
09041          }
09042          if (res == 't')
09043             res = 0;
09044          else if (res == '*')
09045             res = -1;
09046       }
09047       break;
09048       
09049    case 1:  /* Reply */
09050       /* Send reply directly to sender */
09051       if (ast_strlen_zero(cid))
09052          break;
09053 
09054       ast_callerid_parse(cid, &name, &num);
09055       if (!num) {
09056          if (option_verbose > 2)
09057             ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
09058          if (!res)
09059             res = ast_play_and_wait(chan, "vm-nonumber");
09060          ast_config_destroy(msg_cfg);
09061          return res;
09062       } else {
09063          struct ast_vm_user vmu2;
09064          if (find_user(&vmu2, vmu->context, num)) {
09065             struct leave_vm_options leave_options;
09066             char mailbox[AST_MAX_EXTENSION * 2 + 2];
09067             snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
09068 
09069             if (option_verbose > 2)
09070                ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
09071             
09072             memset(&leave_options, 0, sizeof(leave_options));
09073             leave_options.record_gain = record_gain;
09074             res = leave_voicemail(chan, mailbox, &leave_options);
09075             if (!res)
09076                res = 't';
09077             ast_config_destroy(msg_cfg);
09078             return res;
09079          } else {
09080             /* Sender has no mailbox, can't reply */
09081             if (option_verbose > 2)
09082                ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
09083             ast_play_and_wait(chan, "vm-nobox");
09084             res = 't';
09085             ast_config_destroy(msg_cfg);
09086             return res;
09087          }
09088       } 
09089       res = 0;
09090 
09091       break;
09092    }
09093 
09094 #ifndef IMAP_STORAGE
09095    ast_config_destroy(msg_cfg);
09096 
09097    if (!res) {
09098       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
09099       vms->heard[msg] = 1;
09100       res = wait_file(chan, vms, vms->fn);
09101    }
09102 #endif
09103    return res;
09104 }

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

Definition at line 7960 of file app_voicemail.c.

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

Referenced by load_config().

07961 {
07962    /* Assumes lock is already held */
07963    char *tmp;
07964    char *stringp;
07965    char *s;
07966    struct ast_vm_user *vmu;
07967 
07968    tmp = ast_strdupa(data);
07969 
07970    if ((vmu = find_or_create(context, mbox))) {
07971       populate_defaults(vmu);
07972 
07973       stringp = tmp;
07974       if ((s = strsep(&stringp, ","))) 
07975          ast_copy_string(vmu->password, s, sizeof(vmu->password));
07976       if (stringp && (s = strsep(&stringp, ","))) 
07977          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
07978       if (stringp && (s = strsep(&stringp, ","))) 
07979          ast_copy_string(vmu->email, s, sizeof(vmu->email));
07980       if (stringp && (s = strsep(&stringp, ","))) 
07981          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
07982       if (stringp && (s = strsep(&stringp, ","))) 
07983          apply_options(vmu, s);
07984    }
07985    return 0;
07986 }

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

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

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

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

Definition at line 697 of file app_voicemail.c.

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

Referenced by append_mailbox(), and apply_option().

00698 {  /* Destructively Parse options and apply */
00699    char *stringp;
00700    char *s;
00701    char *var, *value;
00702    stringp = ast_strdupa(options);
00703    while ((s = strsep(&stringp, "|"))) {
00704       value = s;
00705       if ((var = strsep(&value, "=")) && value) {
00706          apply_option(vmu, var, value);
00707       }
00708    }  
00709 }

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

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

00712 {
00713    struct ast_variable *tmp;
00714    tmp = var;
00715    while (tmp) {
00716       if (!strcasecmp(tmp->name, "vmsecret")) {
00717          ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00718       } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
00719          if (ast_strlen_zero(retval->password))
00720             ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00721       } else if (!strcasecmp(tmp->name, "uniqueid")) {
00722          ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00723       } else if (!strcasecmp(tmp->name, "pager")) {
00724          ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00725       } else if (!strcasecmp(tmp->name, "email")) {
00726          ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00727       } else if (!strcasecmp(tmp->name, "fullname")) {
00728          ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00729       } else if (!strcasecmp(tmp->name, "context")) {
00730          ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00731 #ifdef IMAP_STORAGE
00732       } else if (!strcasecmp(tmp->name, "imapuser")) {
00733          ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
00734       } else if (!strcasecmp(tmp->name, "imappassword") || !strcasecmp(tmp->name, "imapsecret")) {
00735          ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
00736       } else if (!strcasecmp(tmp->name, "imapvmshareid")) {
00737          ast_copy_string(retval->imapvmshareid, tmp->value, sizeof(retval->imapvmshareid));
00738 #endif
00739       } else
00740          apply_option(retval, tmp->name, tmp->value);
00741       tmp = tmp->next;
00742    } 
00743 }

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

Definition at line 2922 of file app_voicemail.c.

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

Referenced by make_email_file().

02923 {
02924    unsigned char dtable[BASEMAXINLINE];
02925    int i,hiteof= 0;
02926    FILE *fi;
02927    struct baseio bio;
02928 
02929    memset(&bio, 0, sizeof(bio));
02930    bio.iocp = BASEMAXINLINE;
02931 
02932    if (!(fi = fopen(filename, "rb"))) {
02933       ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
02934       return -1;
02935    }
02936 
02937    for (i= 0;i<9;i++) {
02938       dtable[i]= 'A'+i;
02939       dtable[i+9]= 'J'+i;
02940       dtable[26+i]= 'a'+i;
02941       dtable[26+i+9]= 'j'+i;
02942    }
02943    for (i= 0;i<8;i++) {
02944       dtable[i+18]= 'S'+i;
02945       dtable[26+i+18]= 's'+i;
02946    }
02947    for (i= 0;i<10;i++) {
02948       dtable[52+i]= '0'+i;
02949    }
02950    dtable[62]= '+';
02951    dtable[63]= '/';
02952 
02953    while (!hiteof){
02954       unsigned char igroup[3],ogroup[4];
02955       int c,n;
02956 
02957       igroup[0]= igroup[1]= igroup[2]= 0;
02958 
02959       for (n= 0;n<3;n++) {
02960          if ((c = inchar(&bio, fi)) == EOF) {
02961             hiteof= 1;
02962             break;
02963          }
02964 
02965          igroup[n]= (unsigned char)c;
02966       }
02967 
02968       if (n> 0) {
02969          ogroup[0]= dtable[igroup[0]>>2];
02970          ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)];
02971          ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)];
02972          ogroup[3]= dtable[igroup[2]&0x3F];
02973 
02974          if (n<3) {
02975             ogroup[3]= '=';
02976 
02977             if (n<2)
02978                ogroup[2]= '=';
02979          }
02980 
02981          for (i= 0;i<4;i++)
02982             ochar(&bio, ogroup[i], so);
02983       }
02984    }
02985 
02986    fclose(fi);
02987    
02988    if (fputs(eol,so)==EOF)
02989       return 0;
02990 
02991    return 1;
02992 }

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

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

00682 {
00683    int res;
00684    if (!ast_strlen_zero(vmu->uniqueid)) {
00685       res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL);
00686       if (res > 0) {
00687          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00688          res = 0;
00689       } else if (!res) {
00690          res = -1;
00691       }
00692       return res;
00693    }
00694    return -1;
00695 }

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

Referenced by make_email_file().

03091 {
03092    for (; *str; str++) {
03093       if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
03094          return 1;
03095       }
03096    }
03097    return 0;
03098 }

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

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

05757 {
05758    int x = 0;
05759 #ifndef IMAP_STORAGE
05760    int res = 0, nummsg;
05761 #endif
05762 
05763    if (vms->lastmsg <= -1)
05764       goto done;
05765 
05766    vms->curmsg = -1; 
05767 #ifndef IMAP_STORAGE
05768    /* Get the deleted messages fixed */ 
05769    if (vm_lock_path(vms->curdir))
05770       return ERROR_LOCK_PATH;
05771     
05772    for (x = 0; x < vmu->maxmsg; x++) { 
05773       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
05774          /* Save this message.  It's not in INBOX or hasn't been heard */ 
05775          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
05776          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
05777             break;
05778          vms->curmsg++; 
05779          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
05780          if (strcmp(vms->fn, vms->fn2)) { 
05781             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
05782          } 
05783       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
05784          /* Move to old folder before deleting */ 
05785          res = save_to_folder(vmu, vms, x, 1);
05786          if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) {
05787             /* If save failed do not delete the message */
05788             ast_log(LOG_WARNING, "Save failed.  Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
05789             vms->deleted[x] = 0;
05790             vms->heard[x] = 0;
05791             --x;
05792          } 
05793       } 
05794    } 
05795 
05796    /* Delete ALL remaining messages */
05797    nummsg = x - 1;
05798    for (x = vms->curmsg + 1; x <= nummsg; x++) {
05799       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
05800       if (EXISTS(vms->curdir, x, vms->fn, NULL))
05801          DELETE(vms->curdir, x, vms->fn, vmu);
05802    }
05803    ast_unlock_path(vms->curdir);
05804 #else
05805    if (vms->deleted) {
05806       for (x=0;x < vmu->maxmsg;x++) { 
05807          if (vms->deleted[x]) { 
05808             if (option_debug > 2)
05809                ast_log(LOG_DEBUG,"IMAP delete of %d\n",x);
05810             DELETE(vms->curdir, x, vms->fn, vmu);
05811          }
05812       }
05813    }
05814 #endif
05815 
05816 done:
05817    if (vms->deleted)
05818       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
05819    if (vms->heard)
05820       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
05821 
05822    return 0;
05823 }

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

Definition at line 8149 of file app_voicemail.c.

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

08150 {
08151    int which = 0;
08152    int wordlen;
08153    struct ast_vm_user *vmu;
08154    const char *context = "";
08155 
08156    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
08157    if (pos > 4)
08158       return NULL;
08159    if (pos == 3)
08160       return (state == 0) ? ast_strdup("for") : NULL;
08161    wordlen = strlen(word);
08162    AST_LIST_TRAVERSE(&users, vmu, list) {
08163       if (!strncasecmp(word, vmu->context, wordlen)) {
08164          if (context && strcmp(context, vmu->context) && ++which > state)
08165             return ast_strdup(vmu->context);
08166          /* ignore repeated contexts ? */
08167          context = vmu->context;
08168       }
08169    }
08170    return NULL;
08171 }

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

Definition at line 2800 of file app_voicemail.c.

References ast_log(), errno, and VOICEMAIL_FILE_MODE.

02801 {
02802    int ifd;
02803    int ofd;
02804    int res;
02805    int len;
02806    char buf[4096];
02807 
02808 #ifdef HARDLINK_WHEN_POSSIBLE
02809    /* Hard link if possible; saves disk space & is faster */
02810    if (link(infile, outfile)) {
02811 #endif
02812       if ((ifd = open(infile, O_RDONLY)) < 0) {
02813          ast_log(LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno));
02814          return -1;
02815       }
02816       if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
02817          ast_log(LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno));
02818          close(ifd);
02819          return -1;
02820       }
02821       do {
02822          len = read(ifd, buf, sizeof(buf));
02823          if (len < 0) {
02824             ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
02825             close(ifd);
02826             close(ofd);
02827             unlink(outfile);
02828          }
02829          if (len) {
02830             res = write(ofd, buf, len);
02831             if (errno == ENOMEM || errno == ENOSPC || res != len) {
02832                ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
02833                close(ifd);
02834                close(ofd);
02835                unlink(outfile);
02836             }
02837          }
02838       } while (len);
02839       close(ifd);
02840       close(ofd);
02841       return 0;
02842 #ifdef HARDLINK_WHEN_POSSIBLE
02843    } else {
02844       /* Hard link succeeded */
02845       return 0;
02846    }
02847 #endif
02848 }

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 3764 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().

03765 {
03766    char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
03767    const char *frombox = mbox(imbox);
03768    int recipmsgnum;
03769 
03770    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
03771 
03772    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
03773    
03774    if (!dir)
03775       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
03776    else
03777       ast_copy_string(fromdir, dir, sizeof(fromdir));
03778 
03779    make_file(frompath, sizeof(frompath), fromdir, msgnum);
03780 
03781    if (vm_lock_path(todir))
03782       return ERROR_LOCK_PATH;
03783 
03784    recipmsgnum = 0;
03785    do {
03786       make_file(topath, sizeof(topath), todir, recipmsgnum);
03787       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
03788          break;
03789       recipmsgnum++;
03790    } while (recipmsgnum < recip->maxmsg);
03791    if (recipmsgnum < recip->maxmsg) {
03792       if (EXISTS(fromdir, msgnum, frompath, chan->language)) {
03793          COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
03794       } else {
03795          /* For ODBC storage, if the file we want to copy isn't yet in the database, then the SQL
03796           * copy will fail. Instead, we need to create a local copy, store it, and delete the local
03797           * copy. We don't have to #ifdef this because if file storage reaches this point, there's a
03798           * much worse problem happening and IMAP storage doesn't call this function
03799           */
03800          copy_plain_file(frompath, topath);
03801          STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL);
03802          vm_delete(topath);
03803       }
03804    } else {
03805       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
03806    }
03807    ast_unlock_path(todir);
03808    notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
03809    
03810    return 0;
03811 }

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

Definition at line 2850 of file app_voicemail.c.

References ast_filecopy(), and copy().

Referenced by copy_message(), and forward_message().

02851 {
02852    char frompath2[PATH_MAX], topath2[PATH_MAX];
02853    ast_filecopy(frompath, topath, NULL);
02854    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
02855    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
02856    copy(frompath2, topath2);
02857 }

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

Definition at line 2716 of file app_voicemail.c.

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

Referenced by leave_voicemail(), and open_mailbox().

02717 {
02718    /* Find all .txt files - even if they are not in sequence from 0000 */
02719 
02720    int vmcount = 0;
02721    DIR *vmdir = NULL;
02722    struct dirent *vment = NULL;
02723 
02724    if (vm_lock_path(dir))
02725       return ERROR_LOCK_PATH;
02726 
02727    if ((vmdir = opendir(dir))) {
02728       while ((vment = readdir(vmdir))) {
02729          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
02730             vmcount++;
02731       }
02732       closedir(vmdir);
02733    }
02734    ast_unlock_path(dir);
02735    
02736    return vmcount;
02737 }

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 941 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().

00942 {
00943    mode_t   mode = VOICEMAIL_DIR_MODE;
00944 
00945    if (!ast_strlen_zero(context)) {
00946       make_dir(dest, len, context, "", "");
00947       if (mkdir(dest, mode) && errno != EEXIST) {
00948          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00949          return -1;
00950       }
00951    }
00952    if (!ast_strlen_zero(ext)) {
00953       make_dir(dest, len, context, ext, "");
00954       if (mkdir(dest, mode) && errno != EEXIST) {
00955          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00956          return -1;
00957       }
00958    }
00959    if (!ast_strlen_zero(folder)) {
00960       make_dir(dest, len, context, ext, folder);
00961       if (mkdir(dest, mode) && errno != EEXIST) {
00962          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00963          return -1;
00964       }
00965    }
00966    return 0;
00967 }

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

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

08855 {
08856    int cmd = 0;
08857    char destination[80] = "";
08858    int retries = 0;
08859 
08860    if (!num) {
08861       if (option_verbose > 2)
08862          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
08863       while (retries < 3 && cmd != 't') {
08864          destination[1] = '\0';
08865          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
08866          if (!cmd)
08867             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
08868          if (!cmd)
08869             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
08870          if (!cmd) {
08871             cmd = ast_waitfordigit(chan, 6000);
08872             if (cmd)
08873                destination[0] = cmd;
08874          }
08875          if (!cmd) {
08876             retries++;
08877          } else {
08878 
08879             if (cmd < 0)
08880                return 0;
08881             if (cmd == '*') {
08882                if (option_verbose > 2)
08883                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
08884                return 0;
08885             }
08886             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
08887                retries++;
08888             else
08889                cmd = 't';
08890          }
08891       }
08892       if (retries >= 3) {
08893          return 0;
08894       }
08895       
08896    } else {
08897       if (option_verbose > 2)
08898          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
08899       ast_copy_string(destination, num, sizeof(destination));
08900    }
08901 
08902    if (!ast_strlen_zero(destination)) {
08903       if (destination[strlen(destination) -1 ] == '*')
08904          return 0; 
08905       if (option_verbose > 2)
08906          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
08907       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
08908       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
08909       chan->priority = 0;
08910       return 9;
08911    }
08912    return 0;
08913 }

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

Referenced by make_email_file().

03117 {
03118    char tmp[80];
03119    int first_section = 1;
03120    size_t endlen = 0, tmplen = 0;
03121    *end = '\0';
03122 
03123    tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03124    for (; *start; start++) {
03125       int need_encoding = 0;
03126       if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) {
03127          need_encoding = 1;
03128       }
03129       if ((first_section && need_encoding && preamble + tmplen > 70) ||
03130          (first_section && !need_encoding && preamble + tmplen > 72) ||
03131          (!first_section && need_encoding && tmplen > 70) ||
03132          (!first_section && !need_encoding && tmplen > 72)) {
03133          /* Start new line */
03134          endlen += snprintf(end + endlen, endsize - endlen, "%s%s?=", first_section ? "" : " ", tmp);
03135          tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03136          first_section = 0;
03137       }
03138       if (need_encoding && *start == ' ') {
03139          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "_");
03140       } else if (need_encoding) {
03141          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "=%hhX", *start);
03142       } else {
03143          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%c", *start);
03144       }
03145    }
03146    snprintf(end + endlen, endsize - endlen, "%s%s?=%s", first_section ? "" : " ", tmp, endlen + postamble > 74 ? " " : "");
03147    return end;
03148 }

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

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

07933 {
07934    struct ast_vm_user *vmu;
07935    AST_LIST_TRAVERSE(&users, vmu, list) {
07936       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox)) {
07937          if (strcasecmp(vmu->context, context)) {
07938             ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\
07939                   \n\tcontexts and that you have the 'searchcontexts' option on. This type of\
07940                   \n\tconfiguration creates an ambiguity that you likely do not want. Please\
07941                   \n\tamend your voicemail.conf file to avoid this situation.\n", mbox);
07942          }
07943          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", mbox);
07944          return NULL;
07945       }
07946       if (!strcasecmp(context, vmu->context) && !strcasecmp(mbox, vmu->mailbox)) {
07947          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", mbox, context);
07948          return NULL;
07949       }
07950    }
07951    
07952    if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
07953       ast_copy_string(vmu->context, context, sizeof(vmu->context));
07954       ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
07955       AST_LIST_INSERT_TAIL(&users, vmu, list);
07956    }
07957    return vmu;
07958 }

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

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

00775 {
00776    /* This function could be made to generate one from a database, too */
00777    struct ast_vm_user *vmu=NULL, *cur;
00778    AST_LIST_LOCK(&users);
00779 
00780    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00781       context = "default";
00782 
00783    AST_LIST_TRAVERSE(&users, cur, list) {
00784       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00785          break;
00786       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00787          break;
00788    }
00789    if (cur) {
00790       /* Make a copy, so that on a reload, we have no race */
00791       if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
00792          memcpy(vmu, cur, sizeof(*vmu));
00793          ast_set2_flag(vmu, !ivm, VM_ALLOCED);
00794          AST_LIST_NEXT(vmu, list) = NULL;
00795       }
00796    } else
00797       vmu = find_user_realtime(ivm, context, mailbox);
00798    AST_LIST_UNLOCK(&users);
00799    return vmu;
00800 }

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

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

00746 {
00747    struct ast_variable *var;
00748    struct ast_vm_user *retval;
00749 
00750    if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
00751       if (!ivm)
00752          ast_set_flag(retval, VM_ALLOCED);   
00753       else
00754          memset(retval, 0, sizeof(*retval));
00755       if (mailbox) 
00756          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00757       populate_defaults(retval);
00758       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00759          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00760       else
00761          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00762       if (var) {
00763          apply_options_full(retval, var);
00764          ast_variables_destroy(var);
00765       } else { 
00766          if (!ivm) 
00767             free(retval);
00768          retval = NULL;
00769       }  
00770    } 
00771    return retval;
00772 }

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 5138 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().

05139 {
05140 #ifdef IMAP_STORAGE
05141    int todircount=0;
05142    struct vm_state *dstvms;
05143 #endif
05144    char username[70]="";
05145    int res = 0, cmd = 0;
05146    struct ast_vm_user *receiver = NULL, *vmtmp;
05147    AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
05148    char *stringp;
05149    const char *s;
05150    int saved_messages = 0, found = 0;
05151    int valid_extensions = 0;
05152    char *dir;
05153    int curmsg;
05154 
05155    if (vms == NULL) return -1;
05156    dir = vms->curdir;
05157    curmsg = vms->curmsg;
05158    
05159    while (!res && !valid_extensions) {
05160       int use_directory = 0;
05161       if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
05162          int done = 0;
05163          int retries = 0;
05164          cmd=0;
05165          while ((cmd >= 0) && !done ){
05166             if (cmd)
05167                retries = 0;
05168             switch (cmd) {
05169             case '1': 
05170                use_directory = 0;
05171                done = 1;
05172                break;
05173             case '2': 
05174                use_directory = 1;
05175                done=1;
05176                break;
05177             case '*': 
05178                cmd = 't';
05179                done = 1;
05180                break;
05181             default: 
05182                /* Press 1 to enter an extension press 2 to use the directory */
05183                cmd = ast_play_and_wait(chan,"vm-forward");
05184                if (!cmd)
05185                   cmd = ast_waitfordigit(chan,3000);
05186                if (!cmd)
05187                   retries++;
05188                if (retries > 3)
05189                {
05190                   cmd = 't';
05191                   done = 1;
05192                }
05193                
05194             }
05195          }
05196          if (cmd < 0 || cmd == 't')
05197             break;
05198       }
05199       
05200       if (use_directory) {
05201          /* use app_directory */
05202          
05203          char old_context[sizeof(chan->context)];
05204          char old_exten[sizeof(chan->exten)];
05205          int old_priority;
05206          struct ast_app* app;
05207 
05208          
05209          app = pbx_findapp("Directory");
05210          if (app) {
05211             char vmcontext[256];
05212             /* make backup copies */
05213             memcpy(old_context, chan->context, sizeof(chan->context));
05214             memcpy(old_exten, chan->exten, sizeof(chan->exten));
05215             old_priority = chan->priority;
05216             
05217             /* call the the Directory, changes the channel */
05218             snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default");
05219             res = pbx_exec(chan, app, vmcontext);
05220             
05221             ast_copy_string(username, chan->exten, sizeof(username));
05222             
05223             /* restore the old context, exten, and priority */
05224             memcpy(chan->context, old_context, sizeof(chan->context));
05225             memcpy(chan->exten, old_exten, sizeof(chan->exten));
05226             chan->priority = old_priority;
05227             
05228          } else {
05229             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
05230             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
05231          }
05232       } else {
05233          /* Ask for an extension */
05234          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
05235          if (res)
05236             break;
05237          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
05238             break;
05239       }
05240       
05241       /* start all over if no username */
05242       if (ast_strlen_zero(username))
05243          continue;
05244       stringp = username;
05245       s = strsep(&stringp, "*");
05246       /* start optimistic */
05247       valid_extensions = 1;
05248       while (s) {
05249          /* 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 */
05250          if ((flag == 1 || strcmp(s,sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
05251             AST_LIST_INSERT_HEAD(&extensions, receiver, list);
05252             found++;
05253          } else {
05254             ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s);
05255             valid_extensions = 0;
05256             break;
05257          }
05258          s = strsep(&stringp, "*");
05259       }
05260       /* break from the loop of reading the extensions */
05261       if (valid_extensions)
05262          break;
05263       /* "I am sorry, that's not a valid extension.  Please try again." */
05264       res = ast_play_and_wait(chan, "pbx-invalid");
05265    }
05266    /* check if we're clear to proceed */
05267    if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
05268       return res;
05269    if (flag==1) {
05270       struct leave_vm_options leave_options;
05271       char mailbox[AST_MAX_EXTENSION * 2 + 2];
05272       /* Make sure that context doesn't get set as a literal "(null)" (or else find_user won't find it) */
05273       if (context)
05274          snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
05275       else
05276          ast_copy_string(mailbox, username, sizeof(mailbox));
05277 
05278       /* Send VoiceMail */
05279       memset(&leave_options, 0, sizeof(leave_options));
05280       leave_options.record_gain = record_gain;
05281       cmd = leave_voicemail(chan, mailbox, &leave_options);
05282    } else {
05283       /* Forward VoiceMail */
05284       long duration = 0;
05285       char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
05286       struct vm_state vmstmp;
05287 
05288       memcpy(&vmstmp, vms, sizeof(vmstmp));
05289 
05290       make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
05291       create_dirpath(vmstmp.curdir, sizeof(vmstmp.curdir), sender->context, vmstmp.username, "tmp");
05292       make_file(msgfile, sizeof(msgfile), vmstmp.curdir, curmsg);
05293 
05294       RETRIEVE(dir, curmsg, sender);
05295 
05296       /* Alter a surrogate file, only */
05297       copy_plain_file(origmsgfile, msgfile);
05298 
05299       cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp);
05300       if (!cmd) {
05301          AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
05302 #ifdef IMAP_STORAGE
05303             char *myserveremail;
05304             int attach_user_voicemail;
05305             /* get destination mailbox */
05306             dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0);
05307             if (!dstvms) {
05308                dstvms = create_vm_state_from_user(vmtmp);
05309             }
05310             if (dstvms) {
05311                init_mailstream(dstvms, 0);
05312                if (!dstvms->mailstream) {
05313                   ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
05314                } else {
05315                   STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
05316                   run_externnotify(vmtmp->context, vmtmp->mailbox); 
05317                }
05318             } else {
05319                ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
05320             }
05321             myserveremail = serveremail;
05322             if (!ast_strlen_zero(vmtmp->serveremail))
05323                myserveremail = vmtmp->serveremail;
05324             attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
05325             /* NULL category for IMAP storage */
05326             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);
05327 #else
05328             copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir);
05329 #endif
05330             saved_messages++;
05331             AST_LIST_REMOVE_CURRENT(&extensions, list);
05332             free_user(vmtmp);
05333             if (res)
05334                break;
05335          }
05336          AST_LIST_TRAVERSE_SAFE_END;
05337          if (saved_messages > 0) {
05338             /* give confirmation that the message was saved */
05339             /* commented out since we can't forward batches yet
05340             if (saved_messages == 1)
05341                res = ast_play_and_wait(chan, "vm-message");
05342             else
05343                res = ast_play_and_wait(chan, "vm-messages");
05344             if (!res)
05345                res = ast_play_and_wait(chan, "vm-saved"); */
05346             res = ast_play_and_wait(chan, "vm-msgsaved");
05347          }  
05348       }
05349 
05350       /* Remove surrogate file */
05351       vm_delete(msgfile);
05352       DISPOSE(dir, curmsg);
05353    }
05354 
05355    /* If anything failed above, we still have this list to free */
05356    while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list)))
05357       free_user(vmtmp);
05358    return res ? res : cmd;
05359 }

static void free_user ( struct ast_vm_user vmu  )  [static]

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

00987 {
00988    if (ast_test_flag(vmu, VM_ALLOCED))
00989       free(vmu);
00990 }

static void free_vm_users ( void   )  [static]

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

08194 {
08195    struct ast_vm_user *cur;
08196    struct vm_zone *zcur;
08197 
08198    AST_LIST_LOCK(&users);
08199    while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
08200       ast_set_flag(cur, VM_ALLOCED);
08201       free_user(cur);
08202    }
08203    AST_LIST_UNLOCK(&users);
08204 
08205    AST_LIST_LOCK(&zones);
08206    while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) {
08207       free_zone(zcur);
08208    }
08209    AST_LIST_UNLOCK(&zones);
08210 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 3607 of file app_voicemail.c.

References free.

03608 {
03609    free(z);
03610 }

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

Definition at line 3540 of file app_voicemail.c.

References ast_localtime().

Referenced by leave_voicemail(), and tds_log().

03541 {
03542    struct tm tm;
03543    time_t t;
03544 
03545    time(&t);
03546 
03547    ast_localtime(&t, &tm, NULL);
03548 
03549    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
03550 }

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

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

04937 {
04938    int x;
04939    int d;
04940    char fn[PATH_MAX];
04941    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
04942    if (d)
04943       return d;
04944    for (x = start; x< 5; x++) {  /* For all folders */
04945       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
04946          return d;
04947       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
04948       if (d)
04949          return d;
04950       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
04951       d = vm_play_folder_name(chan, fn);
04952       if (d)
04953          return d;
04954       d = ast_waitfordigit(chan, 500);
04955       if (d)
04956          return d;
04957    }
04958    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
04959    if (d)
04960       return d;
04961    d = ast_waitfordigit(chan, 4000);
04962    return d;
04963 }

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

Definition at line 4965 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

04966 {
04967    int res = 0;
04968    res = ast_play_and_wait(chan, fn);  /* Folder name */
04969    while (((res < '0') || (res > '9')) &&
04970          (res != '#') && (res >= 0)) {
04971       res = get_folder(chan, 0);
04972    }
04973    return res;
04974 }

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

Definition at line 8079 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.

08080 {
08081    struct ast_vm_user *vmu;
08082    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
08083 
08084    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
08085    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
08086 
08087    AST_LIST_LOCK(&users);
08088    if (!AST_LIST_EMPTY(&users)) {
08089       if (argc == 3)
08090          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08091       else {
08092          int count = 0;
08093          AST_LIST_TRAVERSE(&users, vmu, list) {
08094             if (!strcmp(argv[4],vmu->context))
08095                count++;
08096          }
08097          if (count) {
08098             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08099          } else {
08100             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
08101             AST_LIST_UNLOCK(&users);
08102             return RESULT_FAILURE;
08103          }
08104       }
08105       AST_LIST_TRAVERSE(&users, vmu, list) {
08106          int newmsgs = 0, oldmsgs = 0;
08107          char count[12], tmp[256] = "";
08108 
08109          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
08110             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
08111             inboxcount(tmp, &newmsgs, &oldmsgs);
08112             snprintf(count,sizeof(count),"%d",newmsgs);
08113             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
08114          }
08115       }
08116    } else {
08117       ast_cli(fd, "There are no voicemail users currently defined\n");
08118       AST_LIST_UNLOCK(&users);
08119       return RESULT_FAILURE;
08120    }
08121    AST_LIST_UNLOCK(&users);
08122    return RESULT_SUCCESS;
08123 }

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

Definition at line 8125 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.

08126 {
08127    struct vm_zone *zone;
08128    char *output_format = "%-15s %-20s %-45s\n";
08129    int res = RESULT_SUCCESS;
08130 
08131    if (argc != 3)
08132       return RESULT_SHOWUSAGE;
08133 
08134    AST_LIST_LOCK(&zones);
08135    if (!AST_LIST_EMPTY(&zones)) {
08136       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
08137       AST_LIST_TRAVERSE(&zones, zone, list) {
08138          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
08139       }
08140    } else {
08141       ast_cli(fd, "There are no voicemail zones currently defined\n");
08142       res = RESULT_FAILURE;
08143    }
08144    AST_LIST_UNLOCK(&zones);
08145 
08146    return res;
08147 }

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

Definition at line 3851 of file app_voicemail.c.

References __has_voicemail(), and ast_copy_string().

03852 {
03853    char tmp[256], *tmp2 = tmp, *mbox, *context;
03854    ast_copy_string(tmp, mailbox, sizeof(tmp));
03855    while ((mbox = strsep(&tmp2, ","))) {
03856       if ((context = strchr(mbox, '@')))
03857          *context++ = '\0';
03858       else
03859          context = "default";
03860       if (__has_voicemail(context, mbox, folder, 1))
03861          return 1;
03862    }
03863    return 0;
03864 }

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

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

03868 {
03869    char tmp[256];
03870    char *context;
03871 
03872    if (newmsgs)
03873       *newmsgs = 0;
03874    if (oldmsgs)
03875       *oldmsgs = 0;
03876    /* If no mailbox, return immediately */
03877    if (ast_strlen_zero(mailbox))
03878       return 0;
03879    if (strchr(mailbox, ',')) {
03880       int tmpnew, tmpold;
03881       char *mb, *cur;
03882 
03883       ast_copy_string(tmp, mailbox, sizeof(tmp));
03884       mb = tmp;
03885       while ((cur = strsep(&mb, ", "))) {
03886          if (!ast_strlen_zero(cur)) {
03887             if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
03888                return -1;
03889             else {
03890                if (newmsgs)
03891                   *newmsgs += tmpnew; 
03892                if (oldmsgs)
03893                   *oldmsgs += tmpold;
03894             }
03895          }
03896       }
03897       return 0;
03898    }
03899    ast_copy_string(tmp, mailbox, sizeof(tmp));
03900    context = strchr(tmp, '@');
03901    if (context) {
03902       *context = '\0';
03903       context++;
03904    } else
03905       context = "default";
03906    if (newmsgs)
03907       *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
03908    if (oldmsgs)
03909       *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
03910    return 0;
03911 }

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

Definition at line 2874 of file app_voicemail.c.

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

Referenced by inchar(), and sip_addheader().

02875 {
02876    int l;
02877 
02878    if (bio->ateof)
02879       return 0;
02880 
02881    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
02882       if (ferror(fi))
02883          return -1;
02884 
02885       bio->ateof = 1;
02886       return 0;
02887    }
02888 
02889    bio->iolen= l;
02890    bio->iocp= 0;
02891 
02892    return 1;
02893 }

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

Definition at line 2895 of file app_voicemail.c.

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

Referenced by base_encode().

02896 {
02897    if (bio->iocp>=bio->iolen) {
02898       if (!inbuf(bio, fi))
02899          return EOF;
02900    }
02901 
02902    return bio->iobuf[bio->iocp++];
02903 }

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

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

03579 {
03580    int res;
03581    char fn[PATH_MAX];
03582    char dest[PATH_MAX];
03583 
03584    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, ext);
03585 
03586    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "greet"))) {
03587       ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
03588       return -1;
03589    }
03590 
03591    res = play_greeting(chan, vmu, fn, ecodes);
03592    if (res == -2) {
03593       /* File did not exist */
03594       res = ast_stream_and_wait(chan, "vm-theperson", chan->language, ecodes);
03595       if (res)
03596          return res;
03597       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
03598    }
03599 
03600    if (res)
03601       return res;
03602 
03603    res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language, ecodes);
03604    return res;
03605 }

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

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

02755 {
02756    int x;
02757    char fn[PATH_MAX];
02758 
02759    if (vm_lock_path(dir))
02760       return ERROR_LOCK_PATH;
02761 
02762    for (x = 0; x < vmu->maxmsg; x++) {
02763       make_file(fn, sizeof(fn), dir, x);
02764       if (ast_fileexists(fn, NULL, NULL) < 1)
02765          break;
02766    }
02767    ast_unlock_path(dir);
02768 
02769    return x - 1;
02770 }

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

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

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

static int load_config ( void   )  [static]

Definition at line 8212 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_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.

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

static int load_module ( void   )  [static]

Definition at line 8803 of file app_voicemail.c.

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

08804 {
08805    int res;
08806    char *adsi_loaded = ast_module_helper("", "res_adsi.so", 0, 0, 0, 0);
08807    char *smdi_loaded = ast_module_helper("", "res_smdi.so", 0, 0, 0, 0);
08808    free(adsi_loaded);
08809    free(smdi_loaded);
08810 
08811    if (!adsi_loaded) {
08812       /* If embedded, res_adsi may be known as "res_adsi" not "res_adsi.so" */
08813       adsi_loaded = ast_module_helper("", "res_adsi", 0, 0, 0, 0);
08814       ast_free(adsi_loaded);
08815       if (!adsi_loaded) {
08816          ast_log(LOG_ERROR, "app_voicemail.so depends upon res_adsi.so\n");
08817          return AST_MODULE_LOAD_DECLINE;
08818       }
08819    }
08820 
08821    if (!smdi_loaded) {
08822       /* If embedded, res_smdi may be known as "res_smdi" not "res_smdi.so" */
08823       smdi_loaded = ast_module_helper("", "res_smdi", 0, 0, 0, 0);
08824       ast_free(smdi_loaded);
08825       if (!smdi_loaded) {
08826          ast_log(LOG_ERROR, "app_voicemail.so depends upon res_smdi.so\n");
08827          return AST_MODULE_LOAD_DECLINE;
08828       }
08829    }
08830 
08831    my_umask = umask(0);
08832    umask(my_umask);
08833    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
08834    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
08835    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
08836    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
08837    if (res)
08838       return(res);
08839 
08840    if ((res=load_config())) {
08841       return(res);
08842    }
08843 
08844    ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08845 
08846    /* compute the location of the voicemail spool directory */
08847    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
08848 
08849    ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
08850 
08851    return res;
08852 }

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

Definition at line 907 of file app_voicemail.c.

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

00908 {
00909    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
00910 }

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 3150 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_channel::priority, quote(), strip_control(), VM_PBXSKIP, vmu_tm(), VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.

Referenced by sendmail().

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

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

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

00913 {
00914    return snprintf(dest, len, "%s/msg%04d", dir, num);
00915 }

static char* mbox ( int  id  )  [static]

Definition at line 969 of file app_voicemail.c.

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

00970 {
00971    static char *msgs[] = {
00972       "INBOX",
00973       "Old",
00974       "Work",
00975       "Family",
00976       "Friends",
00977       "Cust1",
00978       "Cust2",
00979       "Cust3",
00980       "Cust4",
00981       "Cust5",
00982    };
00983    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "tmp";
00984 }

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

Definition at line 3814 of file app_voicemail.c.

References __has_voicemail().

Referenced by load_module().

03815 {
03816    return __has_voicemail(context, mailbox, folder, 0);
03817 }

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 5078 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().

05079 {
05080    char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
05081    int newmsgs = 0, oldmsgs = 0;
05082    const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
05083 
05084    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
05085    make_file(fn, sizeof(fn), todir, msgnum);
05086    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
05087 
05088    if (!ast_strlen_zero(vmu->attachfmt)) {
05089       if (strstr(fmt, vmu->attachfmt)) {
05090          fmt = vmu->attachfmt;
05091       } else {
05092          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);
05093       }
05094    }
05095 
05096    /* Attach only the first format */
05097    fmt = ast_strdupa(fmt);
05098    stringp = fmt;
05099    strsep(&stringp, "|");
05100 
05101    if (!ast_strlen_zero(vmu->email)) {
05102       int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
05103       char *myserveremail = serveremail;
05104       attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
05105       if (!ast_strlen_zero(vmu->serveremail))
05106          myserveremail = vmu->serveremail;
05107       
05108       if (attach_user_voicemail)
05109          RETRIEVE(todir, msgnum, vmu);
05110 
05111       /*XXX possible imap issue, should category be NULL XXX*/
05112       sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
05113 
05114       if (attach_user_voicemail)
05115          DISPOSE(todir, msgnum);
05116    }
05117 
05118    if (!ast_strlen_zero(vmu->pager)) {
05119       char *myserveremail = serveremail;
05120       if (!ast_strlen_zero(vmu->serveremail))
05121          myserveremail = vmu->serveremail;
05122       sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, duration, vmu, category);
05123    }
05124 
05125    if (ast_test_flag(vmu, VM_DELETE)) {
05126       DELETE(todir, msgnum, fn, vmu);
05127    }
05128 
05129    /* Leave voicemail for someone */
05130    if (ast_app_has_voicemail(ext_context, NULL)) {
05131       ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
05132    }
05133    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);
05134    run_externnotify(vmu->context, vmu->mailbox);
05135    return 0;
05136 }

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

Definition at line 2905 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

02906 {
02907    if (bio->linelength>=BASELINELEN) {
02908       if (fputs(eol,so)==EOF)
02909          return -1;
02910 
02911       bio->linelength= 0;
02912    }
02913 
02914    if (putc(((unsigned char)c),so)==EOF)
02915       return -1;
02916 
02917    bio->linelength++;
02918 
02919    return 1;
02920 }

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

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

05714 {
05715    int res = 0;
05716    int count_msg, last_msg;
05717 
05718    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
05719    
05720    /* Rename the member vmbox HERE so that we don't try to return before
05721     * we know what's going on.
05722     */
05723    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
05724    
05725    /* Faster to make the directory than to check if it exists. */
05726    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
05727 
05728    count_msg = count_messages(vmu, vms->curdir);
05729    if (count_msg < 0)
05730       return count_msg;
05731    else
05732       vms->lastmsg = count_msg - 1;
05733 
05734    /*
05735    The following test is needed in case sequencing gets messed up.
05736    There appears to be more than one way to mess up sequence, so
05737    we will not try to find all of the root causes--just fix it when
05738    detected.
05739    */
05740 
05741    last_msg = last_message_index(vmu, vms->curdir);
05742    if (last_msg < 0)
05743       return last_msg;
05744    else if (vms->lastmsg != last_msg)
05745    {
05746       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
05747       res = resequence_mailbox(vmu, vms->curdir);
05748       if (res)
05749          return res;
05750    }
05751 
05752    return 0;
05753 }

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

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

03553 {
03554    int res = -2;
03555 
03556 #ifdef ODBC_STORAGE
03557    int success = 
03558 #endif
03559    RETRIEVE(filename, -1, vmu);
03560    if (ast_fileexists(filename, NULL, NULL) > 0) {
03561       res = ast_streamfile(chan, filename, chan->language);
03562       if (res > -1) 
03563          res = ast_waitstream(chan, ecodes);
03564 #ifdef ODBC_STORAGE
03565       if (success == -1) {
03566          /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
03567          if (option_debug)
03568             ast_log(LOG_DEBUG, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
03569          store_file(filename, vmu->mailbox, vmu->context, -1);
03570       }
03571 #endif
03572    }
03573    DISPOSE(filename, -1);
03574 
03575    return res;
03576 }

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

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

05580 {
05581    int res = 0;
05582    char filename[256], *cid;
05583    const char *origtime, *context, *category, *duration;
05584    struct ast_config *msg_cfg;
05585 
05586    vms->starting = 0; 
05587    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
05588    adsi_message(chan, vms);
05589    
05590    if (!strcasecmp(chan->language, "he")) {        /* HEBREW FORMAT */
05591       /*
05592        * The syntax in hebrew for counting the number of message is up side down
05593        * in comparison to english.
05594        */
05595       if (!vms->curmsg) {
05596          res = wait_file2(chan, vms, "vm-message");
05597          res = wait_file2(chan, vms, "vm-first");    /* "First" */
05598       } else if (vms->curmsg == vms->lastmsg) {
05599          res = wait_file2(chan, vms, "vm-message");
05600          res = wait_file2(chan, vms, "vm-last");     /* "last" */
05601       } else {
05602          res = wait_file2(chan, vms, "vm-message");  /* "message" */
05603          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05604             ast_log(LOG_DEBUG, "curmsg: %d\n", vms->curmsg);
05605             ast_log(LOG_DEBUG, "lagmsg: %d\n", vms->lastmsg);
05606             if (!res) {
05607                res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
05608             }
05609          }
05610       }     
05611 
05612    } else if (!strncasecmp(chan->language, "pl",2)) {    /* POLISH FORMAT */
05613       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05614          int ten, one;
05615          char nextmsg[256];
05616          ten = (vms->curmsg + 1) / 10;
05617          one = (vms->curmsg + 1) % 10;
05618             
05619          if (vms->curmsg < 20) {
05620             snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
05621             res = wait_file2(chan, vms, nextmsg);
05622          } else {
05623             snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
05624             res = wait_file2(chan, vms, nextmsg);
05625             if (one > 0) {
05626                if (!res) {
05627                   snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
05628                   res = wait_file2(chan, vms, nextmsg);
05629                }
05630             }
05631          }
05632       }
05633       if (!res)
05634          res = wait_file2(chan, vms, "vm-message");         
05635 
05636    } else if (!strncasecmp(chan->language, "se",2)) {    /* SWEDISH FORMAT */
05637       if (!vms->curmsg)
05638          res = wait_file2(chan, vms, "vm-first");  /* "First" */
05639       else if (vms->curmsg == vms->lastmsg)
05640          res = wait_file2(chan, vms, "vm-last");      /* "last" */      
05641       res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
05642       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05643          if (!res)
05644             res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
05645       }
05646       /* We know that the difference between English and Swedish
05647        * is very small, however, we differ the two for standartization
05648        * purposes, and possible changes to either of these in the 
05649        * future
05650        */
05651    } else {
05652       if (!vms->curmsg)                      /* Default syntax */
05653          res = wait_file2(chan, vms, "vm-first");  /* "First" */
05654       else if (vms->curmsg == vms->lastmsg)
05655          res = wait_file2(chan, vms, "vm-last");      /* "last" */      
05656       res = wait_file2(chan, vms, "vm-message");
05657       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05658          if (!res)
05659             res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
05660       }
05661    }
05662 
05663    /* Retrieve info from VM attribute file */
05664    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
05665    snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
05666    RETRIEVE(vms->curdir, vms->curmsg, vmu);
05667    msg_cfg = ast_config_load(filename);
05668    if (!msg_cfg) {
05669       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
05670       return 0;
05671    }
05672 
05673    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
05674       ast_log(LOG_WARNING, "No origtime?!\n");
05675       DISPOSE(vms->curdir, vms->curmsg);
05676       ast_config_destroy(msg_cfg);
05677       return 0;
05678    }
05679 
05680    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
05681    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
05682    category = ast_variable_retrieve(msg_cfg, "message", "category");
05683 
05684    context = ast_variable_retrieve(msg_cfg, "message", "context");
05685    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
05686       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
05687    if (!res)
05688       res = play_message_category(chan, category);
05689    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
05690       res = play_message_datetime(chan, vmu, origtime, filename);
05691    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
05692       res = play_message_callerid(chan, vms, cid, context, 0);
05693    if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
05694       res = play_message_duration(chan, vms, duration, vmu->saydurationm);
05695    /* Allow pressing '1' to skip envelope / callerid */
05696    if (res == '1')
05697       res = 0;
05698    ast_config_destroy(msg_cfg);
05699 
05700    if (!res) {
05701       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
05702       vms->heard[vms->curmsg] = 1;
05703       if ((res = wait_file(chan, vms, vms->fn)) < 0) {
05704          ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn);
05705          res = 0;
05706       }
05707    }
05708    DISPOSE(vms->curdir, vms->curmsg);
05709    return res;
05710 }

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

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

05462 {
05463    int res = 0;
05464    int i;
05465    char *callerid, *name;
05466    char prefile[PATH_MAX] = "";
05467    
05468 
05469    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
05470    /* 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 */
05471    if ((cid == NULL)||(context == NULL))
05472       return res;
05473 
05474    /* Strip off caller ID number from name */
05475    if (option_debug > 2)
05476       ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
05477    ast_callerid_parse(cid, &name, &callerid);
05478    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
05479       /* Check for internal contexts and only */
05480       /* say extension when the call didn't come from an internal context in the list */
05481       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
05482          if (option_debug > 2)
05483             ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
05484          if ((strcmp(cidinternalcontexts[i], context) == 0))
05485             break;
05486       }
05487       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
05488          if (!res) {
05489             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
05490             if (!ast_strlen_zero(prefile)) {
05491             /* See if we can find a recorded name for this person instead of their extension number */
05492                if (ast_fileexists(prefile, NULL, NULL) > 0) {
05493                   if (option_verbose > 2)
05494                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
05495                   if (!callback)
05496                      res = wait_file2(chan, vms, "vm-from");
05497                   res = ast_stream_and_wait(chan, prefile, chan->language, "");
05498                } else {
05499                   if (option_verbose > 2)
05500                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
05501                   /* BB: Say "from extension" as one saying to sound smoother */
05502                   if (!callback)
05503                      res = wait_file2(chan, vms, "vm-from-extension");
05504                   res = ast_say_digit_str(chan, callerid, "", chan->language);
05505                }
05506             }
05507          }
05508       }
05509 
05510       else if (!res){
05511          if (option_debug > 2)
05512             ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
05513          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
05514          if (!callback)
05515             res = wait_file2(chan, vms, "vm-from-phonenumber");
05516          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
05517       }
05518    } else {
05519       /* Number unknown */
05520       if (option_debug)
05521          ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
05522       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
05523       res = wait_file2(chan, vms, "vm-unknown-caller");
05524    }
05525    return res;
05526 }

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

Definition at line 5374 of file app_voicemail.c.

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

Referenced by play_message().

05375 {
05376    int res = 0;
05377 
05378    if (!ast_strlen_zero(category))
05379       res = ast_play_and_wait(chan, category);
05380 
05381    if (res) {
05382       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
05383       res = 0;
05384    }
05385 
05386    return res;
05387 }

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

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

05390 {
05391    int res = 0;
05392    struct vm_zone *the_zone = NULL;
05393    time_t t;
05394 
05395    if (ast_get_time_t(origtime, &t, 0, NULL)) {
05396       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
05397       return 0;
05398    }
05399 
05400    /* Does this user have a timezone specified? */
05401    if (!ast_strlen_zero(vmu->zonetag)) {
05402       /* Find the zone in the list */
05403       struct vm_zone *z;
05404       AST_LIST_LOCK(&zones);
05405       AST_LIST_TRAVERSE(&zones, z, list) {
05406          if (!strcmp(z->name, vmu->zonetag)) {
05407             the_zone = z;
05408             break;
05409          }
05410       }
05411       AST_LIST_UNLOCK(&zones);
05412    }
05413 
05414 /* No internal variable parsing for now, so we'll comment it out for the time being */
05415 #if 0
05416    /* Set the DIFF_* variables */
05417    ast_localtime(&t, &time_now, NULL);
05418    tv_now = ast_tvnow();
05419    tnow = tv_now.tv_sec;
05420    ast_localtime(&tnow, &time_then, NULL);
05421 
05422    /* Day difference */
05423    if (time_now.tm_year == time_then.tm_year)
05424       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
05425    else
05426       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
05427    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
05428 
05429    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
05430 #endif
05431    if (the_zone)
05432       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
05433    else if (!strncasecmp(chan->language,"pl",2))       /* POLISH syntax */
05434       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
05435    else if (!strncasecmp(chan->language,"se",2))       /* SWEDISH syntax */
05436       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
05437    else if (!strncasecmp(chan->language,"no",2))       /* NORWEGIAN syntax */
05438       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05439    else if (!strncasecmp(chan->language,"de",2))       /* GERMAN syntax */
05440       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05441    else if (!strncasecmp(chan->language,"nl",2))      /* DUTCH syntax */
05442       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
05443    else if (!strncasecmp(chan->language,"it",2))      /* ITALIAN syntax */
05444       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);
05445    else if (!strncasecmp(chan->language,"gr",2))
05446       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
05447    else if (!strcasecmp(chan->language,"pt_BR"))
05448       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);      
05449    else if (!strcasecmp(chan->language,"he"))
05450       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'at2' kM", NULL);
05451    else
05452       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
05453 #if 0
05454    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
05455 #endif
05456    return res;
05457 }

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

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

05529 {
05530    int res = 0;
05531    int durationm;
05532    int durations;
05533    /* Verify that we have a duration for the message */
05534    if (duration == NULL)
05535       return res;
05536 
05537    /* Convert from seconds to minutes */
05538    durations=atoi(duration);
05539    durationm=(durations / 60);
05540 
05541    if (option_debug > 2)
05542       ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
05543 
05544    if ((!res) && (durationm >= minduration)) {
05545       res = wait_file2(chan, vms, "vm-duration");
05546 
05547       /* POLISH syntax */
05548       if (!strncasecmp(chan->language, "pl",2)) {
05549          div_t num = div(durationm, 10);
05550 
05551          if (durationm == 1) {
05552             res = ast_play_and_wait(chan, "digits/1z");
05553             res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
05554          } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05555             if (num.rem == 2) {
05556                if (!num.quot) {
05557                   res = ast_play_and_wait(chan, "digits/2-ie");
05558                } else {
05559                   res = say_and_wait(chan, durationm - 2 , chan->language);
05560                   res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05561                }
05562             } else {
05563                res = say_and_wait(chan, durationm, chan->language);
05564             }
05565             res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
05566          } else {
05567             res = say_and_wait(chan, durationm, chan->language);
05568             res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
05569          }
05570       /* DEFAULT syntax */
05571       } else {
05572          res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
05573          res = wait_file2(chan, vms, "vm-minutes");
05574       }
05575    }
05576    return res;
05577 }

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 9106 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().

09109 {
09110    /* Record message & let caller review or re-record it, or set options if applicable */
09111    int res = 0;
09112    int cmd = 0;
09113    int max_attempts = 3;
09114    int attempts = 0;
09115    int recorded = 0;
09116    int message_exists = 0;
09117    signed char zero_gain = 0;
09118    char tempfile[PATH_MAX];
09119    char *acceptdtmf = "#";
09120    char *canceldtmf = "";
09121 
09122    /* Note that urgent and private are for flagging messages as such in the future */
09123 
09124    /* barf if no pointer passed to store duration in */
09125    if (duration == NULL) {
09126       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
09127       return -1;
09128    }
09129 
09130    if (!outsidecaller)
09131       snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
09132    else
09133       ast_copy_string(tempfile, recordfile, sizeof(tempfile));
09134 
09135    cmd = '3';  /* Want to start by recording */
09136 
09137    while ((cmd >= 0) && (cmd != 't')) {
09138       switch (cmd) {
09139       case '1':
09140          if (!message_exists) {
09141             /* In this case, 1 is to record a message */
09142             cmd = '3';
09143             break;
09144          } else {
09145             /* Otherwise 1 is to save the existing message */
09146             if (option_verbose > 2)
09147                ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
09148             if (!outsidecaller)
09149                ast_filerename(tempfile, recordfile, NULL);
09150             ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
09151             if (!outsidecaller) {
09152                STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
09153                DISPOSE(recordfile, -1);
09154             }
09155             cmd = 't';
09156             return res;
09157          }
09158       case '2':
09159          /* Review */
09160          if (option_verbose > 2)
09161             ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
09162          cmd = ast_stream_and_wait(chan, tempfile, chan->language, AST_DIGIT_ANY);
09163          break;
09164       case '3':
09165          message_exists = 0;
09166          /* Record */
09167          if (recorded == 1) {
09168             if (option_verbose > 2)
09169                ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
09170          } else { 
09171             if (option_verbose > 2)
09172                ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
09173          }
09174          if (recorded && outsidecaller) {
09175             cmd = ast_play_and_wait(chan, INTRO);
09176             cmd = ast_play_and_wait(chan, "beep");
09177          }
09178          recorded = 1;
09179          /* 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 */
09180          if (record_gain)
09181             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
09182          if (ast_test_flag(vmu, VM_OPERATOR))
09183             canceldtmf = "0";
09184          cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
09185          if (record_gain)
09186             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
09187          if (cmd == -1) {
09188             /* User has hung up, no options to give */
09189             if (!outsidecaller) {
09190                /* user was recording a greeting and they hung up, so let's delete the recording. */
09191                ast_filedelete(tempfile, NULL);
09192             }
09193             return cmd;
09194          }
09195          if (cmd == '0') {
09196             break;
09197          } else if (cmd == '*') {
09198             break;
09199          } 
09200 #if 0       
09201          else if (vmu->review && (*duration < 5)) {
09202             /* Message is too short */
09203             if (option_verbose > 2)
09204                ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
09205             cmd = ast_play_and_wait(chan, "vm-tooshort");
09206             cmd = ast_filedelete(tempfile, NULL);
09207             break;
09208          }
09209          else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
09210             /* Message is all silence */
09211             if (option_verbose > 2)
09212                ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
09213             cmd = ast_filedelete(tempfile, NULL);
09214             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
09215             if (!cmd)
09216                cmd = ast_play_and_wait(chan, "vm-speakup");
09217             break;
09218          }
09219 #endif
09220          else {
09221             /* If all is well, a message exists */
09222             message_exists = 1;
09223             cmd = 0;
09224          }
09225          break;
09226       case '4':
09227       case '5':
09228       case '6':
09229       case '7':
09230       case '8':
09231       case '9':
09232       case '*':
09233       case '#':
09234          cmd = ast_play_and_wait(chan, "vm-sorry");
09235          break;
09236 #if 0 
09237 /*  XXX Commented out for the moment because of the dangers of deleting
09238     a message while recording (can put the message numbers out of sync) */
09239       case '*':
09240          /* Cancel recording, delete message, offer to take another message*/
09241          cmd = ast_play_and_wait(chan, "vm-deleted");
09242          cmd = ast_filedelete(tempfile, NULL);
09243          if (outsidecaller) {
09244             res = vm_exec(chan, NULL);
09245             return res;
09246          }
09247          else
09248             return 1;
09249 #endif
09250       case '0':
09251          if (!ast_test_flag(vmu, VM_OPERATOR)) {
09252             cmd = ast_play_and_wait(chan, "vm-sorry");
09253             break;
09254          }
09255          if (message_exists || recorded) {
09256             cmd = ast_play_and_wait(chan, "vm-saveoper");
09257             if (!cmd)
09258                cmd = ast_waitfordigit(chan, 3000);
09259             if (cmd == '1') {
09260                ast_play_and_wait(chan, "vm-msgsaved");
09261                cmd = '0';
09262             } else {
09263                ast_play_and_wait(chan, "vm-deleted");
09264                DELETE(recordfile, -1, recordfile, vmu);
09265                cmd = '0';
09266             }
09267          }
09268          return cmd;
09269       default:
09270          /* If the caller is an ouside caller, and the review option is enabled,
09271             allow them to review the message, but let the owner of the box review
09272             their OGM's */
09273          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
09274             return cmd;
09275          if (message_exists) {
09276             cmd = ast_play_and_wait(chan, "vm-review");
09277          }
09278          else {
09279             cmd = ast_play_and_wait(chan, "vm-torerecord");
09280             if (!cmd)
09281                cmd = ast_waitfordigit(chan, 600);
09282          }
09283          
09284          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
09285             cmd = ast_play_and_wait(chan, "vm-reachoper");
09286             if (!cmd)
09287                cmd = ast_waitfordigit(chan, 600);
09288          }
09289 #if 0
09290          if (!cmd)
09291             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
09292 #endif
09293          if (!cmd)
09294             cmd = ast_waitfordigit(chan, 6000);
09295          if (!cmd) {
09296             attempts++;
09297          }
09298          if (attempts > max_attempts) {
09299             cmd = 't';
09300          }
09301       }
09302    }
09303    if (outsidecaller)
09304       ast_play_and_wait(chan, "vm-goodbye");
09305    if (cmd == 't')
09306       cmd = 0;
09307    return cmd;
09308 }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

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

00599 {
00600    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00601    if (saydurationminfo)
00602       vmu->saydurationm = saydurationminfo;
00603    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00604    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00605    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00606    ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag));
00607    if (maxmsg)
00608       vmu->maxmsg = maxmsg;
00609    vmu->volgain = volgain;
00610 }

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 2994 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().

02995 {
02996    char callerid[256];
02997    char fromdir[256], fromfile[256];
02998    struct ast_config *msg_cfg;
02999    const char *origcallerid, *origtime;
03000    char origcidname[80], origcidnum[80], origdate[80];
03001    int inttime;
03002 
03003    /* Prepare variables for substition in email body and subject */
03004    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
03005    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
03006    snprintf(passdata, passdatasize, "%d", msgnum);
03007    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
03008    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
03009    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
03010    pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ?
03011       ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller");
03012    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller"));
03013    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller"));
03014    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
03015    pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
03016 
03017    /* Retrieve info from VM attribute file */
03018    make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
03019    make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1);
03020    if (strlen(fromfile) < sizeof(fromfile) - 5) {
03021       strcat(fromfile, ".txt");
03022    }
03023    if (!(msg_cfg = ast_config_load(fromfile))) {
03024       if (option_debug > 0) {
03025          ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile);
03026       }
03027       return;
03028    }
03029 
03030    if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
03031       pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid);
03032       ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum));
03033       pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname);
03034       pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum);
03035    }
03036 
03037    if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) {
03038       time_t ttime = inttime;
03039       struct tm tm;
03040       ast_localtime(&ttime, &tm, NULL);
03041       strftime(origdate, sizeof(origdate), emaildateformat, &tm);
03042       pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate);
03043    }
03044    ast_config_destroy(msg_cfg);
03045 }

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

Definition at line 3047 of file app_voicemail.c.

03048 {
03049    char *ptr = to;
03050    *ptr++ = '"';
03051    for (; ptr < to + len - 1; from++) {
03052       if (*from == '"')
03053          *ptr++ = '\\';
03054       else if (*from == '\0')
03055          break;
03056       *ptr++ = *from;
03057    }
03058    if (ptr < to + len - 1)
03059       *ptr++ = '"';
03060    *ptr = '\0';
03061    return to;
03062 }

static int reload ( void   )  [static]

Definition at line 8782 of file app_voicemail.c.

References load_config().

08783 {
08784    return(load_config());
08785 }

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

Definition at line 2739 of file app_voicemail.c.

References ast_filerename().

02740 {
02741    char stxt[PATH_MAX];
02742    char dtxt[PATH_MAX];
02743    ast_filerename(sfn,dfn,NULL);
02744    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
02745    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
02746    rename(stxt, dtxt);
02747 }

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

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

04349 {
04350    /* we know max messages, so stop process when number is hit */
04351 
04352    int x,dest;
04353    char sfn[PATH_MAX];
04354    char dfn[PATH_MAX];
04355 
04356    if (vm_lock_path(dir))
04357       return ERROR_LOCK_PATH;
04358 
04359    for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
04360       make_file(sfn, sizeof(sfn), dir, x);
04361       if (EXISTS(dir, x, sfn, NULL)) {
04362          
04363          if (x != dest) {
04364             make_file(dfn, sizeof(dfn), dir, dest);
04365             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
04366          }
04367          
04368          dest++;
04369       }
04370    }
04371    ast_unlock_path(dir);
04372 
04373    return 0;
04374 }

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

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

00803 {
00804    /* This function could be made to generate one from a database, too */
00805    struct ast_vm_user *cur;
00806    int res = -1;
00807    AST_LIST_LOCK(&users);
00808    AST_LIST_TRAVERSE(&users, cur, list) {
00809       if ((!context || !strcasecmp(context, cur->context)) &&
00810          (!strcasecmp(mailbox, cur->mailbox)))
00811             break;
00812    }
00813    if (cur) {
00814       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00815       res = 0;
00816    }
00817    AST_LIST_UNLOCK(&users);
00818    return res;
00819 }

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

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

03916 {
03917    char arguments[255];
03918    char ext_context[256] = "";
03919    int newvoicemails = 0, oldvoicemails = 0;
03920    struct ast_smdi_mwi_message *mwi_msg;
03921 
03922    if (!ast_strlen_zero(context))
03923       snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
03924    else
03925       ast_copy_string(ext_context, extension, sizeof(ext_context));
03926 
03927    if (!strcasecmp(externnotify, "smdi")) {
03928       if (ast_app_has_voicemail(ext_context, NULL)) 
03929          ast_smdi_mwi_set(smdi_iface, extension);
03930       else
03931          ast_smdi_mwi_unset(smdi_iface, extension);
03932 
03933       if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) {
03934          ast_log(LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension);
03935          if (!strncmp(mwi_msg->cause, "INV", 3))
03936             ast_log(LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
03937          else if (!strncmp(mwi_msg->cause, "BLK", 3))
03938             ast_log(LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
03939          ast_log(LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
03940          ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
03941       } else {
03942          if (option_debug)
03943             ast_log(LOG_DEBUG, "Successfully executed SMDI MWI change for %s\n", extension);
03944       }
03945    } else if (!ast_strlen_zero(externnotify)) {
03946       if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
03947          ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
03948       } else {
03949          snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
03950          if (option_debug)
03951             ast_log(LOG_DEBUG, "Executing %s\n", arguments);
03952          ast_safe_system(arguments);
03953       }
03954    }
03955 }

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

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

04385 {
04386 #ifdef IMAP_STORAGE
04387    /* we must use mbox(x) folder names, and copy the message there */
04388    /* simple. huh? */
04389    char sequence[10];
04390    /* get the real IMAP message number for this message */
04391    snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
04392    if (option_debug > 2)
04393       ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,(char *) mbox(box));
04394    ast_mutex_lock(&vms->lock);
04395    if (box == 1) {
04396       mail_setflag(vms->mailstream, sequence, "\\Seen");
04397    } else if (box == 0) {
04398       mail_clearflag(vms->mailstream, sequence, "\\Seen");
04399    }
04400    if (!strcasecmp(mbox(0), vms->curbox) && (box == 0 || box == 1)) {
04401       ast_mutex_unlock(&vms->lock);
04402       return 0;
04403    } else {
04404       int res = !mail_copy(vms->mailstream,sequence,(char *) mbox(box)); 
04405       ast_mutex_unlock(&vms->lock);
04406       return res;
04407    }
04408 #else
04409    char *dir = vms->curdir;
04410    char *username = vms->username;
04411    char *context = vmu->context;
04412    char sfn[PATH_MAX];
04413    char dfn[PATH_MAX];
04414    char ddir[PATH_MAX];
04415    const char *dbox = mbox(box);
04416    int x;
04417    make_file(sfn, sizeof(sfn), dir, msg);
04418    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
04419 
04420    if (vm_lock_path(ddir))
04421       return ERROR_LOCK_PATH;
04422 
04423    for (x = 0; x < vmu->maxmsg; x++) {
04424       make_file(dfn, sizeof(dfn), ddir, x);
04425       if (!EXISTS(ddir, x, dfn, NULL))
04426          break;
04427    }
04428    if (x >= vmu->maxmsg) {
04429       ast_unlock_path(ddir);
04430       return ERROR_MAILBOX_FULL;
04431    }
04432    if (strcmp(sfn, dfn)) {
04433       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
04434    }
04435    ast_unlock_path(ddir);
04436 #endif
04437    return 0;
04438 }

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

Definition at line 4377 of file app_voicemail.c.

References AST_DIGIT_ANY, and ast_say_number().

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

04378 {
04379    int d;
04380    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
04381    return d;
04382 }

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 3426 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().

03427 {
03428    FILE *p=NULL;
03429    char tmp[80] = "/tmp/astmail-XXXXXX";
03430    char tmp2[256];
03431 
03432    if (vmu && ast_strlen_zero(vmu->email)) {
03433       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
03434       return(0);
03435    }
03436    if (!strcmp(format, "wav49"))
03437       format = "WAV";
03438    if (option_debug > 2)
03439       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));
03440    /* Make a temporary file instead of piping directly to sendmail, in case the mail
03441       command hangs */
03442    if ((p = vm_mkftemp(tmp)) == NULL) {
03443       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03444       return -1;
03445    } else {
03446       make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
03447       fclose(p);
03448       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03449       ast_safe_system(tmp2);
03450       if (option_debug > 2)
03451          ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
03452    }
03453    return 0;
03454 }

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 3456 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().

03457 {
03458    char date[256];
03459    char host[MAXHOSTNAMELEN] = "";
03460    char who[256];
03461    char dur[PATH_MAX];
03462    char tmp[80] = "/tmp/astmail-XXXXXX";
03463    char tmp2[PATH_MAX];
03464    struct tm tm;
03465    FILE *p;
03466 
03467    if ((p = vm_mkftemp(tmp)) == NULL) {
03468       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03469       return -1;
03470    } else {
03471       gethostname(host, sizeof(host)-1);
03472       if (strchr(srcemail, '@'))
03473          ast_copy_string(who, srcemail, sizeof(who));
03474       else {
03475          snprintf(who, sizeof(who), "%s@%s", srcemail, host);
03476       }
03477       snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
03478       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
03479       fprintf(p, "Date: %s\n", date);
03480 
03481       if (*pagerfromstring) {
03482          struct ast_channel *ast;
03483          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03484             char *passdata;
03485             int vmlen = strlen(fromstring)*3 + 200;
03486             if ((passdata = alloca(vmlen))) {
03487                memset(passdata, 0, vmlen);
03488                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03489                pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen);
03490                fprintf(p, "From: %s <%s>\n", passdata, who);
03491             } else 
03492                ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03493             ast_channel_free(ast);
03494          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03495       } else
03496          fprintf(p, "From: Asterisk PBX <%s>\n", who);
03497       fprintf(p, "To: %s\n", pager);
03498       if (pagersubject) {
03499          struct ast_channel *ast;
03500          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03501             char *passdata;
03502             int vmlen = strlen(pagersubject) * 3 + 200;
03503             if ((passdata = alloca(vmlen))) {
03504                memset(passdata, 0, vmlen);
03505                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03506                pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen);
03507                fprintf(p, "Subject: %s\n\n", passdata);
03508             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03509             ast_channel_free(ast);
03510          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03511       } else
03512          fprintf(p, "Subject: New VM\n\n");
03513       strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
03514       if (pagerbody) {
03515          struct ast_channel *ast;
03516          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03517             char *passdata;
03518             int vmlen = strlen(pagerbody)*3 + 200;
03519             if ((passdata = alloca(vmlen))) {
03520                memset(passdata, 0, vmlen);
03521                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03522                pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen);
03523                fprintf(p, "%s\n", passdata);
03524             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03525          ast_channel_free(ast);
03526          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03527       } else {
03528          fprintf(p, "New %s long msg in box %s\n"
03529                "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
03530       }
03531       fclose(p);
03532       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03533       ast_safe_system(tmp2);
03534       if (option_debug > 2)
03535          ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd);
03536    }
03537    return 0;
03538 }

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

Definition at line 582 of file app_voicemail.c.

Referenced by make_email_file().

00583 {
00584    char *bufptr = buf;
00585    for (; *input; input++) {
00586       if (*input < 32) {
00587          continue;
00588       }
00589       *bufptr++ = *input;
00590       if (bufptr == buf + buflen - 1) {
00591          break;
00592       }
00593    }
00594    *bufptr = '\0';
00595    return buf;
00596 }

static int unload_module ( void   )  [static]

Definition at line 8787 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.

08788 {
08789    int res;
08790    
08791    res = ast_unregister_application(app);
08792    res |= ast_unregister_application(app2);
08793    res |= ast_unregister_application(app3);
08794    res |= ast_unregister_application(app4);
08795    ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08796    ast_uninstall_vm_functions();
08797    
08798    ast_module_user_hangup_all();
08799 
08800    return res;
08801 }

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 7153 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().

07156 {
07157    int useadsi=0, valid=0, logretries=0;
07158    char password[AST_MAX_EXTENSION]="", *passptr;
07159    struct ast_vm_user vmus, *vmu = NULL;
07160 
07161    /* If ADSI is supported, setup login screen */
07162    adsi_begin(chan, &useadsi);
07163    if (!skipuser && useadsi)
07164       adsi_login(chan);
07165    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
07166       ast_log(LOG_WARNING, "Couldn't stream login file\n");
07167       return -1;
07168    }
07169    
07170    /* Authenticate them and get their mailbox/password */
07171    
07172    while (!valid && (logretries < maxlogins)) {
07173       /* Prompt for, and read in the username */
07174       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
07175          ast_log(LOG_WARNING, "Couldn't read username\n");
07176          return -1;
07177       }
07178       if (ast_strlen_zero(mailbox)) {
07179          if (chan->cid.cid_num) {
07180             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
07181          } else {
07182             if (option_verbose > 2)
07183                ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");  
07184             return -1;
07185          }
07186       }
07187       if (useadsi)
07188          adsi_password(chan);
07189 
07190       if (!ast_strlen_zero(prefix)) {
07191          char fullusername[80] = "";
07192          ast_copy_string(fullusername, prefix, sizeof(fullusername));
07193          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
07194          ast_copy_string(mailbox, fullusername, mailbox_size);
07195       }
07196 
07197       if (option_debug)
07198          ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
07199       vmu = find_user(&vmus, context, mailbox);
07200       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
07201          /* saved password is blank, so don't bother asking */
07202          password[0] = '\0';
07203       } else {
07204          if (ast_streamfile(chan, "vm-password", chan->language)) {
07205             ast_log(LOG_WARNING, "Unable to stream password file\n");
07206             return -1;
07207          }
07208          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
07209             ast_log(LOG_WARNING, "Unable to read password\n");
07210             return -1;
07211          }
07212       }
07213 
07214       if (vmu) {
07215          passptr = vmu->password;
07216          if (passptr[0] == '-') passptr++;
07217       }
07218       if (vmu && !strcmp(passptr, password))
07219          valid++;
07220       else {
07221          if (option_verbose > 2)
07222             ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
07223          if (!ast_strlen_zero(prefix))
07224             mailbox[0] = '\0';
07225       }
07226       logretries++;
07227       if (!valid) {
07228          if (skipuser || logretries >= maxlogins) {
07229             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
07230                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
07231                return -1;
07232             }
07233          } else {
07234             if (useadsi)
07235                adsi_login(chan);
07236             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
07237                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
07238                return -1;
07239             }
07240          }
07241          if (ast_waitstream(chan, "")) /* Channel is hung up */
07242             return -1;
07243       }
07244    }
07245    if (!valid && (logretries >= maxlogins)) {
07246       ast_stopstream(chan);
07247       ast_play_and_wait(chan, "vm-goodbye");
07248       return -1;
07249    }
07250    if (vmu && !skipuser) {
07251       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
07252    }
07253    return 0;
07254 }

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

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

07989 {
07990    struct ast_module_user *u;
07991    struct ast_vm_user svm;
07992    char *context, *box;
07993    int priority_jump = 0;
07994    AST_DECLARE_APP_ARGS(args,
07995       AST_APP_ARG(mbox);
07996       AST_APP_ARG(options);
07997    );
07998 
07999    if (ast_strlen_zero(data)) {
08000       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
08001       return -1;
08002    }
08003 
08004    u = ast_module_user_add(chan);
08005 
08006    box = ast_strdupa(data);
08007 
08008    AST_STANDARD_APP_ARGS(args, box);
08009 
08010    if (args.options) {
08011       if (strchr(args.options, 'j'))
08012          priority_jump = 1;
08013    }
08014 
08015    if ((context = strchr(args.mbox, '@'))) {
08016       *context = '\0';
08017       context++;
08018    }
08019 
08020    if (find_user(&svm, context, args.mbox)) {
08021       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
08022       if (priority_jump || ast_opt_priority_jumping)
08023          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
08024             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);
08025    } else
08026       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
08027    ast_module_user_remove(u);
08028    return 0;
08029 }

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

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

07140 {
07141    if (!strncasecmp(chan->language, "es", 2) ||
07142          !strncasecmp(chan->language, "it", 2) ||
07143          !strncasecmp(chan->language, "pt", 2) ||
07144          !strncasecmp(chan->language, "gr", 2)) { /* SPANISH, ITALIAN, PORTUGUESE or GREEK */
07145       return vm_browse_messages_latin(chan, vms, vmu);
07146    } else if (!strcasecmp(chan->language, "he")) {
07147       return vm_browse_messages_he(chan, vms, vmu); /* HEBREW */ 
07148    } else { /* Default to English syntax */
07149       return vm_browse_messages_en(chan, vms, vmu);
07150    }
07151 }

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

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

07074 {
07075    int cmd=0;
07076 
07077    if (vms->lastmsg > -1) {
07078       cmd = play_message(chan, vmu, vms);
07079    } else {
07080       cmd = ast_play_and_wait(chan, "vm-youhave");
07081       if (!cmd) 
07082          cmd = ast_play_and_wait(chan, "vm-no");
07083       if (!cmd) {
07084          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07085          cmd = ast_play_and_wait(chan, vms->fn);
07086       }
07087       if (!cmd)
07088          cmd = ast_play_and_wait(chan, "vm-messages");
07089    }
07090    return cmd;
07091 }

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

Definition at line 7094 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07095 {
07096    int cmd = 0;
07097 
07098    if (vms->lastmsg > -1) {
07099       cmd = play_message(chan, vmu, vms);
07100    } else {
07101       if (!strcasecmp(vms->fn, "INBOX")) {
07102          cmd = ast_play_and_wait(chan, "vm-nonewmessages");
07103       } else {
07104          cmd = ast_play_and_wait(chan, "vm-nomessages");
07105       }
07106    }
07107    return cmd;
07108 }

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

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

07113 {
07114    int cmd=0;
07115 
07116    if (vms->lastmsg > -1) {
07117       cmd = play_message(chan, vmu, vms);
07118    } else {
07119       cmd = ast_play_and_wait(chan, "vm-youhaveno");
07120       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
07121          if (!cmd) {
07122             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
07123             cmd = ast_play_and_wait(chan, vms->fn);
07124          }
07125          if (!cmd)
07126             cmd = ast_play_and_wait(chan, "vm-messages");
07127       } else {
07128          if (!cmd)
07129             cmd = ast_play_and_wait(chan, "vm-messages");
07130          if (!cmd) {
07131             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07132             cmd = ast_play_and_wait(chan, vms->fn);
07133          }
07134       }
07135    }
07136    return cmd;
07137 }

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

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

00822 {
00823    struct ast_config   *cfg=NULL;
00824    struct ast_variable *var=NULL;
00825    struct ast_category *cat=NULL;
00826    char *category=NULL, *value=NULL, *new=NULL;
00827    const char *tmp=NULL;
00828                
00829    if (!change_password_realtime(vmu, newpassword))
00830       return;
00831 
00832    /* check voicemail.conf */
00833    if ((cfg = ast_config_load_with_comments(VOICEMAIL_CONFIG))) {
00834       while ((category = ast_category_browse(cfg, category))) {
00835          if (!strcasecmp(category, vmu->context)) {
00836             tmp = ast_variable_retrieve(cfg, category, vmu->mailbox);
00837             if (!tmp) {
00838                ast_log(LOG_WARNING, "We could not find the mailbox.\n");
00839                break;
00840             }
00841             value = strstr(tmp,",");
00842             if (!value) {
00843                ast_log(LOG_WARNING, "variable has bad format.\n");
00844                break;
00845             }
00846             new = alloca((strlen(value)+strlen(newpassword)+1));
00847             sprintf(new,"%s%s", newpassword, value);
00848             if (!(cat = ast_category_get(cfg, category))) {
00849                ast_log(LOG_WARNING, "Failed to get category structure.\n");
00850                break;
00851             }
00852             ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
00853          }
00854       }
00855       /* save the results */
00856       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00857       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00858       config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
00859    }
00860    category = NULL;
00861    var = NULL;
00862    /* check users.conf and update the password stored for the mailbox*/
00863    /* if no vmsecret entry exists create one. */
00864    if ((cfg = ast_config_load_with_comments("users.conf"))) {
00865       if (option_debug > 3)
00866          ast_log(LOG_DEBUG, "we are looking for %s\n", vmu->mailbox);
00867       while ((category = ast_category_browse(cfg, category))) {
00868          if (option_debug > 3)
00869             ast_log(LOG_DEBUG, "users.conf: %s\n", category);
00870          if (!strcasecmp(category, vmu->mailbox)) {
00871             if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) {
00872                if (option_debug > 3)
00873                   ast_log(LOG_DEBUG, "looks like we need to make vmsecret!\n");
00874                var = ast_variable_new("vmsecret", newpassword);
00875             } 
00876             new = alloca(strlen(newpassword)+1);
00877             sprintf(new, "%s", newpassword);
00878             if (!(cat = ast_category_get(cfg, category))) {
00879                if (option_debug > 3)
00880                   ast_log(LOG_DEBUG, "failed to get category!\n");
00881                break;
00882             }
00883             if (!var)      
00884                ast_variable_update(cat, "vmsecret", new, NULL, 0);
00885             else
00886                ast_variable_append(cat, var);
00887          }
00888       }
00889       /* save the results and clean things up */
00890       reset_user_pw(vmu->context, vmu->mailbox, newpassword);  
00891       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00892       config_text_file_save("users.conf", cfg, "AppVoicemail");
00893    }
00894 }

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

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

00897 {
00898    char buf[255];
00899    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00900    if (!ast_safe_system(buf)) {
00901       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00902       /* Reset the password in memory, too */
00903       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00904    }
00905 }

static int vm_delete ( char *  file  )  [static]

Definition at line 2859 of file app_voicemail.c.

References ast_filedelete().

Referenced by copy_message(), and forward_message().

02860 {
02861    char *txt;
02862    int txtsize = 0;
02863 
02864    txtsize = (strlen(file) + 5)*sizeof(char);
02865    txt = alloca(txtsize);
02866    /* Sprintf here would safe because we alloca'd exactly the right length,
02867     * but trying to eliminate all sprintf's anyhow
02868     */
02869    snprintf(txt, txtsize, "%s.txt", file);
02870    unlink(txt);
02871    return ast_filedelete(file, NULL);
02872 }

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

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

07834 {
07835    int res = 0;
07836    struct ast_module_user *u;
07837    char *tmp;
07838    struct leave_vm_options leave_options;
07839    struct ast_flags flags = { 0 };
07840    static int deprecate_warning = 0;
07841    char *opts[OPT_ARG_ARRAY_SIZE];
07842    AST_DECLARE_APP_ARGS(args,
07843       AST_APP_ARG(argv0);
07844       AST_APP_ARG(argv1);
07845    );
07846 
07847    u = ast_module_user_add(chan);
07848    
07849    memset(&leave_options, 0, sizeof(leave_options));
07850 
07851    if (chan->_state != AST_STATE_UP)
07852       ast_answer(chan);
07853 
07854    if (!ast_strlen_zero(data)) {
07855       tmp = ast_strdupa(data);
07856       AST_STANDARD_APP_ARGS(args, tmp);
07857       if (args.argc == 2) {
07858          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
07859             ast_module_user_remove(u);
07860             return -1;
07861          }
07862          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
07863          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07864             int gain;
07865 
07866             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
07867                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07868                ast_module_user_remove(u);
07869                return -1;
07870             } else {
07871                leave_options.record_gain = (signed char) gain;
07872             }
07873          }
07874       } else {
07875          /* old style options parsing */
07876          int old = 0;
07877          char *orig_argv0 = args.argv0;
07878          while (*(args.argv0)) {
07879             if (*(args.argv0) == 's') {
07880                old = 1;
07881                ast_set_flag(&leave_options, OPT_SILENT);
07882             } else if (*(args.argv0) == 'b') {
07883                old = 1;
07884                ast_set_flag(&leave_options, OPT_BUSY_GREETING);
07885             } else if (*(args.argv0) == 'u') {
07886                old = 1;
07887                ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
07888             } else if (*(args.argv0) == 'j') {
07889                old = 1;
07890                ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
07891             } else
07892                break;
07893             (args.argv0)++;
07894          }
07895          if (!deprecate_warning && old) {
07896             deprecate_warning = 1;
07897             ast_log(LOG_WARNING, "Prefixing the mailbox with an option is deprecated ('%s').\n", orig_argv0);
07898             ast_log(LOG_WARNING, "Please move all leading options to the second argument.\n");
07899          }
07900       }
07901    } else {
07902       char tmp[256];
07903       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
07904       if (res < 0) {
07905          ast_module_user_remove(u);
07906          return res;
07907       }
07908       if (ast_strlen_zero(tmp)) {
07909          ast_module_user_remove(u);
07910          return 0;
07911       }
07912       args.argv0 = ast_strdupa(tmp);
07913    }
07914 
07915    res = leave_voicemail(chan, args.argv0, &leave_options);
07916 
07917    if (res == ERROR_LOCK_PATH) {
07918       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
07919       /*Send the call to n+101 priority, where n is the current priority*/
07920       if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
07921          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
07922             ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
07923       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
07924       res = 0;
07925    }
07926    
07927    ast_module_user_remove(u);
07928 
07929    return res;
07930 }

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

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

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

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 4976 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().

04978 {
04979    int cmd = 0;
04980    int retries = 0, prepend_duration = 0, already_recorded = 0;
04981    signed char zero_gain = 0;
04982    struct ast_config *msg_cfg;
04983    const char *duration_str;
04984    char msgfile[PATH_MAX], backup[PATH_MAX];
04985    char textfile[PATH_MAX];
04986 
04987    /* Must always populate duration correctly */
04988    make_file(msgfile, sizeof(msgfile), curdir, curmsg);
04989    strcpy(textfile, msgfile);
04990    strcpy(backup, msgfile);
04991    strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
04992    strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
04993 
04994    if (!(msg_cfg = ast_config_load(textfile))) {
04995       return -1;
04996    }
04997 
04998    *duration = 0;
04999    if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
05000       *duration = atoi(duration_str);
05001 
05002    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
05003       if (cmd)
05004          retries = 0;
05005       switch (cmd) {
05006       case '1': 
05007          /* prepend a message to the current message, update the metadata and return */
05008       {
05009          prepend_duration = 0;
05010 
05011          /* if we can't read the message metadata, stop now */
05012          if (!msg_cfg) {
05013             cmd = 0;
05014             break;
05015          }
05016 
05017          /* Back up the original file, so we can retry the prepend */
05018          if (already_recorded)
05019             ast_filecopy(backup, msgfile, NULL);
05020          else
05021             ast_filecopy(msgfile, backup, NULL);
05022          already_recorded = 1;
05023 
05024          if (record_gain)
05025             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
05026 
05027          cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
05028          if (record_gain)
05029             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
05030 
05031          if (prepend_duration) {
05032             struct ast_category *msg_cat;
05033             /* need enough space for a maximum-length message duration */
05034             char duration_str[12];
05035 
05036             prepend_duration += *duration;
05037             msg_cat = ast_category_get(msg_cfg, "message");
05038             snprintf(duration_str, 11, "%d", prepend_duration);
05039             if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
05040                config_text_file_save(textfile, msg_cfg, "app_voicemail");
05041             }
05042          }
05043 
05044          break;
05045       }
05046       case '2': 
05047          cmd = 't';
05048          break;
05049       case '*':
05050          cmd = '*';
05051          break;
05052       default: 
05053          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
05054             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
05055          if (!cmd)
05056             cmd = ast_play_and_wait(chan,"vm-starmain");
05057             /* "press star to return to the main menu" */
05058          if (!cmd)
05059             cmd = ast_waitfordigit(chan,6000);
05060          if (!cmd)
05061             retries++;
05062          if (retries > 3)
05063             cmd = 't';
05064       }
05065    }
05066 
05067    ast_config_destroy(msg_cfg);
05068    if (already_recorded)
05069       ast_filedelete(backup, NULL);
05070    if (prepend_duration)
05071       *duration = prepend_duration;
05072 
05073    if (cmd == 't' || cmd == 'S')
05074       cmd = 0;
05075    return cmd;
05076 }

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

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

06769 {
06770    int res = 0;
06771    /* Play instructions and wait for new command */
06772    while (!res) {
06773       if (vms->starting) {
06774          if (vms->lastmsg > -1) {
06775             res = ast_play_and_wait(chan, "vm-onefor");
06776             if (!strcasecmp(chan->language, "he")) 
06777                res = ast_play_and_wait(chan, "vm-for");
06778             if (!res)
06779                res = vm_play_folder_name(chan, vms->vmbox);
06780          }
06781          if (!res)
06782             res = ast_play_and_wait(chan, "vm-opts");
06783       } else {
06784          if (vms->curmsg)
06785             res = ast_play_and_wait(chan, "vm-prev");
06786          if (!res && !skipadvanced)
06787             res = ast_play_and_wait(chan, "vm-advopts");
06788          if (!res)
06789             res = ast_play_and_wait(chan, "vm-repeat");
06790          if (!res && (vms->curmsg != vms->lastmsg))
06791             res = ast_play_and_wait(chan, "vm-next");
06792          if (!res) {
06793             if (!vms->deleted[vms->curmsg])
06794                res = ast_play_and_wait(chan, "vm-delete");
06795             else
06796                res = ast_play_and_wait(chan, "vm-undelete");
06797             if (!res)
06798                res = ast_play_and_wait(chan, "vm-toforward");
06799             if (!res)
06800                res = ast_play_and_wait(chan, "vm-savemessage");
06801          }
06802       }
06803       if (!res)
06804          res = ast_play_and_wait(chan, "vm-helpexit");
06805       if (!res)
06806          res = ast_waitfordigit(chan, 6000);
06807       if (!res) {
06808          vms->repeats++;
06809          if (vms->repeats > 2) {
06810             res = 't';
06811          }
06812       }
06813    }
06814    return res;
06815 }

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

Definition at line 6719 of file app_voicemail.c.

References ast_fileexists(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, DISPOSE, ast_channel::language, RETRIEVE, vm_state::username, vm_intro_cz(), 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().

06720 {
06721    char prefile[256];
06722    
06723    /* Notify the user that the temp greeting is set and give them the option to remove it */
06724    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06725    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
06726       RETRIEVE(prefile, -1, vmu);
06727       if (ast_fileexists(prefile, NULL, NULL) > 0)
06728          ast_play_and_wait(chan, "vm-tempgreetactive");
06729       DISPOSE(prefile, -1);
06730    }
06731 
06732    /* Play voicemail intro - syntax is different for different languages */
06733    if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */
06734       return vm_intro_de(chan, vms);
06735    } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */
06736       return vm_intro_es(chan, vms);
06737    } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */
06738       return vm_intro_it(chan, vms);
06739    } else if (!strncasecmp(chan->language, "fr", 2)) {   /* FRENCH syntax */
06740       return vm_intro_fr(chan, vms);
06741    } else if (!strncasecmp(chan->language, "nl", 2)) {   /* DUTCH syntax */
06742       return vm_intro_nl(chan, vms);
06743    } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */
06744       return vm_intro_pt_BR(chan, vms);      
06745    } else if (!strncasecmp(chan->language, "pt", 2)) {   /* PORTUGUESE syntax */
06746       return vm_intro_pt(chan, vms);
06747    } else if (!strncasecmp(chan->language, "cz", 2)) {   /* CZECH syntax */
06748       return vm_intro_cz(chan, vms);
06749    } else if (!strncasecmp(chan->language, "gr", 2)) {   /* GREEK syntax */
06750       return vm_intro_gr(chan, vms);
06751    } else if (!strncasecmp(chan->language, "pl", 2)) {   /* POLISH syntax */
06752       return vm_intro_pl(chan, vms);
06753    } else if (!strncasecmp(chan->language, "se", 2)) {   /* SWEDISH syntax */
06754       return vm_intro_se(chan, vms);
06755    } else if (!strncasecmp(chan->language, "no", 2)) {   /* NORWEGIAN syntax */
06756       return vm_intro_no(chan, vms);
06757    } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */
06758       return vm_intro_multilang(chan, vms, "n");
06759    } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */
06760       return vm_intro_multilang(chan, vms, "n");
06761    } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */
06762       return vm_intro_he(chan, vms);
06763    } else {             /* Default to ENGLISH */
06764       return vm_intro_en(chan, vms);
06765    }
06766 }

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

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

06660 {
06661    int res;
06662    res = ast_play_and_wait(chan, "vm-youhave");
06663    if (!res) {
06664       if (vms->newmessages) {
06665          if (vms->newmessages == 1) {
06666             res = ast_play_and_wait(chan, "digits/jednu");
06667          } else {
06668             res = say_and_wait(chan, vms->newmessages, chan->language);
06669          }
06670          if (!res) {
06671             if ((vms->newmessages == 1))
06672                res = ast_play_and_wait(chan, "vm-novou");
06673             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
06674                res = ast_play_and_wait(chan, "vm-nove");
06675             if (vms->newmessages > 4)
06676                res = ast_play_and_wait(chan, "vm-novych");
06677          }
06678          if (vms->oldmessages && !res)
06679             res = ast_play_and_wait(chan, "vm-and");
06680          else if (!res) {
06681             if ((vms->newmessages == 1))
06682                res = ast_play_and_wait(chan, "vm-zpravu");
06683             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
06684                res = ast_play_and_wait(chan, "vm-zpravy");
06685             if (vms->newmessages > 4)
06686                res = ast_play_and_wait(chan, "vm-zprav");
06687          }
06688       }
06689       if (!res && vms->oldmessages) {
06690          res = say_and_wait(chan, vms->oldmessages, chan->language);
06691          if (!res) {
06692             if ((vms->oldmessages == 1))
06693                res = ast_play_and_wait(chan, "vm-starou");
06694             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
06695                res = ast_play_and_wait(chan, "vm-stare");
06696             if (vms->oldmessages > 4)
06697                res = ast_play_and_wait(chan, "vm-starych");
06698          }
06699          if (!res) {
06700             if ((vms->oldmessages == 1))
06701                res = ast_play_and_wait(chan, "vm-zpravu");
06702             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
06703                res = ast_play_and_wait(chan, "vm-zpravy");
06704             if (vms->oldmessages > 4)
06705                res = ast_play_and_wait(chan, "vm-zprav");
06706          }
06707       }
06708       if (!res) {
06709          if (!vms->oldmessages && !vms->newmessages) {
06710             res = ast_play_and_wait(chan, "vm-no");
06711             if (!res)
06712                res = ast_play_and_wait(chan, "vm-zpravy");
06713          }
06714       }
06715    }
06716    return res;
06717 }

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

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

06353 {
06354    /* Introduce messages they have */
06355    int res;
06356    res = ast_play_and_wait(chan, "vm-youhave");
06357    if (!res) {
06358       if (vms->newmessages) {
06359          if ((vms->newmessages == 1))
06360             res = ast_play_and_wait(chan, "digits/1F");
06361          else
06362             res = say_and_wait(chan, vms->newmessages, chan->language);
06363          if (!res)
06364             res = ast_play_and_wait(chan, "vm-INBOX");
06365          if (vms->oldmessages && !res)
06366             res = ast_play_and_wait(chan, "vm-and");
06367          else if (!res) {
06368             if ((vms->newmessages == 1))
06369                res = ast_play_and_wait(chan, "vm-message");
06370             else
06371                res = ast_play_and_wait(chan, "vm-messages");
06372          }
06373             
06374       }
06375       if (!res && vms->oldmessages) {
06376          if (vms->oldmessages == 1)
06377             res = ast_play_and_wait(chan, "digits/1F");
06378          else
06379             res = say_and_wait(chan, vms->oldmessages, chan->language);
06380          if (!res)
06381             res = ast_play_and_wait(chan, "vm-Old");
06382          if (!res) {
06383             if (vms->oldmessages == 1)
06384                res = ast_play_and_wait(chan, "vm-message");
06385             else
06386                res = ast_play_and_wait(chan, "vm-messages");
06387          }
06388       }
06389       if (!res) {
06390          if (!vms->oldmessages && !vms->newmessages) {
06391             res = ast_play_and_wait(chan, "vm-no");
06392             if (!res)
06393                res = ast_play_and_wait(chan, "vm-messages");
06394          }
06395       }
06396    }
06397    return res;
06398 }

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

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

05951 {
05952    int res;
05953 
05954    /* Introduce messages they have */
05955    res = ast_play_and_wait(chan, "vm-youhave");
05956    if (!res) {
05957       if (vms->newmessages) {
05958          res = say_and_wait(chan, vms->newmessages, chan->language);
05959          if (!res)
05960             res = ast_play_and_wait(chan, "vm-INBOX");
05961          if (vms->oldmessages && !res)
05962             res = ast_play_and_wait(chan, "vm-and");
05963          else if (!res) {
05964             if ((vms->newmessages == 1))
05965                res = ast_play_and_wait(chan, "vm-message");
05966             else
05967                res = ast_play_and_wait(chan, "vm-messages");
05968          }
05969             
05970       }
05971       if (!res && vms->oldmessages) {
05972          res = say_and_wait(chan, vms->oldmessages, chan->language);
05973          if (!res)
05974             res = ast_play_and_wait(chan, "vm-Old");
05975          if (!res) {
05976             if (vms->oldmessages == 1)
05977                res = ast_play_and_wait(chan, "vm-message");
05978             else
05979                res = ast_play_and_wait(chan, "vm-messages");
05980          }
05981       }
05982       if (!res) {
05983          if (!vms->oldmessages && !vms->newmessages) {
05984             res = ast_play_and_wait(chan, "vm-no");
05985             if (!res)
05986                res = ast_play_and_wait(chan, "vm-messages");
05987          }
05988       }
05989    }
05990    return res;
05991 }

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

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

06402 {
06403    /* Introduce messages they have */
06404    int res;
06405    if (!vms->oldmessages && !vms->newmessages) {
06406       res = ast_play_and_wait(chan, "vm-youhaveno");
06407       if (!res)
06408          res = ast_play_and_wait(chan, "vm-messages");
06409    } else {
06410       res = ast_play_and_wait(chan, "vm-youhave");
06411    }
06412    if (!res) {
06413       if (vms->newmessages) {
06414          if (!res) {
06415             if ((vms->newmessages == 1)) {
06416                res = ast_play_and_wait(chan, "digits/1");
06417                if (!res)
06418                   res = ast_play_and_wait(chan, "vm-message");
06419                if (!res)
06420                   res = ast_play_and_wait(chan, "vm-INBOXs");
06421             } else {
06422                res = say_and_wait(chan, vms->newmessages, chan->language);
06423                if (!res)
06424                   res = ast_play_and_wait(chan, "vm-messages");
06425                if (!res)
06426                   res = ast_play_and_wait(chan, "vm-INBOX");
06427             }
06428          }
06429          if (vms->oldmessages && !res)
06430             res = ast_play_and_wait(chan, "vm-and");
06431       }
06432       if (vms->oldmessages) {
06433          if (!res) {
06434             if (vms->oldmessages == 1) {
06435                res = ast_play_and_wait(chan, "digits/1");
06436                if (!res)
06437                   res = ast_play_and_wait(chan, "vm-message");
06438                if (!res)
06439                   res = ast_play_and_wait(chan, "vm-Olds");
06440             } else {
06441                res = say_and_wait(chan, vms->oldmessages, chan->language);
06442                if (!res)
06443                   res = ast_play_and_wait(chan, "vm-messages");
06444                if (!res)
06445                   res = ast_play_and_wait(chan, "vm-Old");
06446             }
06447          }
06448       }
06449    }
06450 return res;
06451 }

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

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

06503 {
06504    /* Introduce messages they have */
06505    int res;
06506    res = ast_play_and_wait(chan, "vm-youhave");
06507    if (!res) {
06508       if (vms->newmessages) {
06509          res = say_and_wait(chan, vms->newmessages, chan->language);
06510          if (!res)
06511             res = ast_play_and_wait(chan, "vm-INBOX");
06512          if (vms->oldmessages && !res)
06513             res = ast_play_and_wait(chan, "vm-and");
06514          else if (!res) {
06515             if ((vms->newmessages == 1))
06516                res = ast_play_and_wait(chan, "vm-message");
06517             else
06518                res = ast_play_and_wait(chan, "vm-messages");
06519          }
06520             
06521       }
06522       if (!res && vms->oldmessages) {
06523          res = say_and_wait(chan, vms->oldmessages, chan->language);
06524          if (!res)
06525             res = ast_play_and_wait(chan, "vm-Old");
06526          if (!res) {
06527             if (vms->oldmessages == 1)
06528                res = ast_play_and_wait(chan, "vm-message");
06529             else
06530                res = ast_play_and_wait(chan, "vm-messages");
06531          }
06532       }
06533       if (!res) {
06534          if (!vms->oldmessages && !vms->newmessages) {
06535             res = ast_play_and_wait(chan, "vm-no");
06536             if (!res)
06537                res = ast_play_and_wait(chan, "vm-messages");
06538          }
06539       }
06540    }
06541    return res;
06542 }

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

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

05913 {
05914    int res = 0;
05915 
05916    if (vms->newmessages) {
05917       res = ast_play_and_wait(chan, "vm-youhave");
05918       if (!res) 
05919          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
05920       if (!res) {
05921          if ((vms->newmessages == 1)) {
05922             res = ast_play_and_wait(chan, "vm-INBOX");
05923             if (!res)
05924                res = ast_play_and_wait(chan, "vm-message");
05925          } else {
05926             res = ast_play_and_wait(chan, "vm-INBOXs");
05927             if (!res)
05928                res = ast_play_and_wait(chan, "vm-messages");
05929          }
05930       }
05931    } else if (vms->oldmessages){
05932       res = ast_play_and_wait(chan, "vm-youhave");
05933       if (!res)
05934          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
05935       if ((vms->oldmessages == 1)){
05936          res = ast_play_and_wait(chan, "vm-Old");
05937          if (!res)
05938             res = ast_play_and_wait(chan, "vm-message");
05939       } else {
05940          res = ast_play_and_wait(chan, "vm-Olds");
05941          if (!res)
05942             res = ast_play_and_wait(chan, "vm-messages");
05943       }
05944    } else if (!vms->oldmessages && !vms->newmessages) 
05945       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
05946    return res;
05947 }

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

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

06091 {
06092    int res=0;
06093 
06094    /* Introduce messages they have */
06095    if (!res) {
06096       if ((vms->newmessages) || (vms->oldmessages)) {
06097          res = ast_play_and_wait(chan, "vm-youhave");
06098       }
06099       /*
06100        * The word "shtei" refers to the number 2 in hebrew when performing a count
06101        * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for
06102        * an element, this is one of them.
06103        */
06104       if (vms->newmessages) {
06105          if (!res) {
06106             if (vms->newmessages == 1) {
06107                res = ast_play_and_wait(chan, "vm-INBOX1");
06108             } else {
06109                if (vms->newmessages == 2) {
06110                   res = ast_play_and_wait(chan, "vm-shtei");
06111                } else {
06112                   res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06113                }
06114                res = ast_play_and_wait(chan, "vm-INBOX");
06115             }
06116          }
06117          if (vms->oldmessages && !res) {
06118             res = ast_play_and_wait(chan, "vm-and");
06119             if (vms->oldmessages == 1) {
06120                res = ast_play_and_wait(chan, "vm-Old1");
06121             } else {
06122                if (vms->oldmessages == 2) {
06123                   res = ast_play_and_wait(chan, "vm-shtei");
06124                } else {
06125                   res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06126                }
06127                res = ast_play_and_wait(chan, "vm-Old");
06128             }
06129          }
06130       }
06131       if (!res && vms->oldmessages && !vms->newmessages) {
06132          if (!res) {
06133             if (vms->oldmessages == 1) {
06134                res = ast_play_and_wait(chan, "vm-Old1");
06135             } else {
06136                if (vms->oldmessages == 2) {
06137                   res = ast_play_and_wait(chan, "vm-shtei");
06138                } else {
06139                   res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");            
06140                }
06141                res = ast_play_and_wait(chan, "vm-Old");
06142             }
06143          }
06144       }
06145       if (!res) {
06146          if (!vms->oldmessages && !vms->newmessages) {
06147             if (!res) {
06148                res = ast_play_and_wait(chan, "vm-nomessages");
06149             }
06150          }
06151       }
06152    }
06153    return res;
06154 }

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

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

06159 {
06160    /* Introduce messages they have */
06161    int res;
06162    if (!vms->oldmessages && !vms->newmessages)
06163       res = ast_play_and_wait(chan, "vm-no") ||
06164          ast_play_and_wait(chan, "vm-message");
06165    else
06166       res = ast_play_and_wait(chan, "vm-youhave");
06167    if (!res && vms->newmessages) {
06168       res = (vms->newmessages == 1) ?
06169          ast_play_and_wait(chan, "digits/un") ||
06170          ast_play_and_wait(chan, "vm-nuovo") ||
06171          ast_play_and_wait(chan, "vm-message") :
06172          /* 2 or more new messages */
06173          say_and_wait(chan, vms->newmessages, chan->language) ||
06174          ast_play_and_wait(chan, "vm-nuovi") ||
06175          ast_play_and_wait(chan, "vm-messages");
06176       if (!res && vms->oldmessages)
06177          res = ast_play_and_wait(chan, "vm-and");
06178    }
06179    if (!res && vms->oldmessages) {
06180       res = (vms->oldmessages == 1) ?
06181          ast_play_and_wait(chan, "digits/un") ||
06182          ast_play_and_wait(chan, "vm-vecchio") ||
06183          ast_play_and_wait(chan, "vm-message") :
06184          /* 2 or more old messages */
06185          say_and_wait(chan, vms->oldmessages, chan->language) ||
06186          ast_play_and_wait(chan, "vm-vecchi") ||
06187          ast_play_and_wait(chan, "vm-messages");
06188    }
06189    return res;
06190 }

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

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

06051 {
06052    int res;
06053    int lastnum = 0;
06054 
06055    res = ast_play_and_wait(chan, "vm-youhave");
06056 
06057    if (!res && vms->newmessages) {
06058       lastnum = vms->newmessages;
06059 
06060       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06061          res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender);
06062       }
06063 
06064       if (!res && vms->oldmessages) {
06065          res = ast_play_and_wait(chan, "vm-and");
06066       }
06067    }
06068 
06069    if (!res && vms->oldmessages) {
06070       lastnum = vms->oldmessages;
06071 
06072       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06073          res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender);
06074       }
06075    }
06076 
06077    if (!res) {
06078       if (lastnum == 0) {
06079          res = ast_play_and_wait(chan, "vm-no");
06080       }
06081       if (!res) {
06082          res = ast_say_counted_noun(chan, lastnum, "vm-message");
06083       }
06084    }
06085 
06086    return res;
06087 }

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

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

06546 {
06547    /* Introduce messages they have */
06548    int res;
06549    res = ast_play_and_wait(chan, "vm-youhave");
06550    if (!res) {
06551       if (vms->newmessages) {
06552          res = say_and_wait(chan, vms->newmessages, chan->language);
06553          if (!res) {
06554             if (vms->newmessages == 1)
06555                res = ast_play_and_wait(chan, "vm-INBOXs");
06556             else
06557                res = ast_play_and_wait(chan, "vm-INBOX");
06558          }
06559          if (vms->oldmessages && !res)
06560             res = ast_play_and_wait(chan, "vm-and");
06561          else if (!res) {
06562             if ((vms->newmessages == 1))
06563                res = ast_play_and_wait(chan, "vm-message");
06564             else
06565                res = ast_play_and_wait(chan, "vm-messages");
06566          }
06567             
06568       }
06569       if (!res && vms->oldmessages) {
06570          res = say_and_wait(chan, vms->oldmessages, chan->language);
06571          if (!res) {
06572             if (vms->oldmessages == 1)
06573                res = ast_play_and_wait(chan, "vm-Olds");
06574             else
06575                res = ast_play_and_wait(chan, "vm-Old");
06576          }
06577          if (!res) {
06578             if (vms->oldmessages == 1)
06579                res = ast_play_and_wait(chan, "vm-message");
06580             else
06581                res = ast_play_and_wait(chan, "vm-messages");
06582          }
06583       }
06584       if (!res) {
06585          if (!vms->oldmessages && !vms->newmessages) {
06586             res = ast_play_and_wait(chan, "vm-no");
06587             if (!res)
06588                res = ast_play_and_wait(chan, "vm-messages");
06589          }
06590       }
06591    }
06592    return res;
06593 }

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

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

06309 {
06310    /* Introduce messages they have */
06311    int res;
06312 
06313    res = ast_play_and_wait(chan, "vm-youhave");
06314    if (res)
06315       return res;
06316 
06317    if (!vms->oldmessages && !vms->newmessages) {
06318       res = ast_play_and_wait(chan, "vm-no");
06319       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06320       return res;
06321    }
06322 
06323    if (vms->newmessages) {
06324       if ((vms->newmessages == 1)) {
06325          res = ast_play_and_wait(chan, "digits/1");
06326          res = res ? res : ast_play_and_wait(chan, "vm-ny");
06327          res = res ? res : ast_play_and_wait(chan, "vm-message");
06328       } else {
06329          res = say_and_wait(chan, vms->newmessages, chan->language);
06330          res = res ? res : ast_play_and_wait(chan, "vm-nye");
06331          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06332       }
06333       if (!res && vms->oldmessages)
06334          res = ast_play_and_wait(chan, "vm-and");
06335    }
06336    if (!res && vms->oldmessages) {
06337       if (vms->oldmessages == 1) {
06338          res = ast_play_and_wait(chan, "digits/1");
06339          res = res ? res : ast_play_and_wait(chan, "vm-gamel");
06340          res = res ? res : ast_play_and_wait(chan, "vm-message");
06341       } else {
06342          res = say_and_wait(chan, vms->oldmessages, chan->language);
06343          res = res ? res : ast_play_and_wait(chan, "vm-gamle");
06344          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06345       }
06346    }
06347 
06348    return res;
06349 }

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

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

06194 {
06195    /* Introduce messages they have */
06196    int res;
06197    div_t num;
06198 
06199    if (!vms->oldmessages && !vms->newmessages) {
06200       res = ast_play_and_wait(chan, "vm-no");
06201       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06202       return res;
06203    } else {
06204       res = ast_play_and_wait(chan, "vm-youhave");
06205    }
06206 
06207    if (vms->newmessages) {
06208       num = div(vms->newmessages, 10);
06209       if (vms->newmessages == 1) {
06210          res = ast_play_and_wait(chan, "digits/1-a");
06211          res = res ? res : ast_play_and_wait(chan, "vm-new-a");
06212          res = res ? res : ast_play_and_wait(chan, "vm-message");
06213       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06214          if (num.rem == 2) {
06215             if (!num.quot) {
06216                res = ast_play_and_wait(chan, "digits/2-ie");
06217             } else {
06218                res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
06219                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06220             }
06221          } else {
06222             res = say_and_wait(chan, vms->newmessages, chan->language);
06223          }
06224          res = res ? res : ast_play_and_wait(chan, "vm-new-e");
06225          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06226       } else {
06227          res = say_and_wait(chan, vms->newmessages, chan->language);
06228          res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
06229          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06230       }
06231       if (!res && vms->oldmessages)
06232          res = ast_play_and_wait(chan, "vm-and");
06233    }
06234    if (!res && vms->oldmessages) {
06235       num = div(vms->oldmessages, 10);
06236       if (vms->oldmessages == 1) {
06237          res = ast_play_and_wait(chan, "digits/1-a");
06238          res = res ? res : ast_play_and_wait(chan, "vm-old-a");
06239          res = res ? res : ast_play_and_wait(chan, "vm-message");
06240       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06241          if (num.rem == 2) {
06242             if (!num.quot) {
06243                res = ast_play_and_wait(chan, "digits/2-ie");
06244             } else {
06245                res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
06246                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06247             }
06248          } else {
06249             res = say_and_wait(chan, vms->oldmessages, chan->language);
06250          }
06251          res = res ? res : ast_play_and_wait(chan, "vm-old-e");
06252          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06253       } else {
06254          res = say_and_wait(chan, vms->oldmessages, chan->language);
06255          res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
06256          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06257       }
06258    }
06259 
06260    return res;
06261 }

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

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

06597 {
06598    /* Introduce messages they have */
06599    int res;
06600    res = ast_play_and_wait(chan, "vm-youhave");
06601    if (!res) {
06602       if (vms->newmessages) {
06603          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06604          if (!res) {
06605             if ((vms->newmessages == 1)) {
06606                res = ast_play_and_wait(chan, "vm-message");
06607                if (!res)
06608                   res = ast_play_and_wait(chan, "vm-INBOXs");
06609             } else {
06610                res = ast_play_and_wait(chan, "vm-messages");
06611                if (!res)
06612                   res = ast_play_and_wait(chan, "vm-INBOX");
06613             }
06614          }
06615          if (vms->oldmessages && !res)
06616             res = ast_play_and_wait(chan, "vm-and");
06617       }
06618       if (!res && vms->oldmessages) {
06619          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06620          if (!res) {
06621             if (vms->oldmessages == 1) {
06622                res = ast_play_and_wait(chan, "vm-message");
06623                if (!res)
06624                   res = ast_play_and_wait(chan, "vm-Olds");
06625             } else {
06626                res = ast_play_and_wait(chan, "vm-messages");
06627                if (!res)
06628                   res = ast_play_and_wait(chan, "vm-Old");
06629             }
06630          }
06631       }
06632       if (!res) {
06633          if (!vms->oldmessages && !vms->newmessages) {
06634             res = ast_play_and_wait(chan, "vm-no");
06635             if (!res)
06636                res = ast_play_and_wait(chan, "vm-messages");
06637          }
06638       }
06639    }
06640    return res;
06641 }

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

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

06454                                                                          {
06455    /* Introduce messages they have */
06456    int res;
06457    if (!vms->oldmessages && !vms->newmessages) {
06458       res = ast_play_and_wait(chan, "vm-nomessages");
06459       return res;
06460    }
06461    else {
06462       res = ast_play_and_wait(chan, "vm-youhave");
06463    }
06464    if (vms->newmessages) {
06465       if (!res)
06466          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06467       if ((vms->newmessages == 1)) {
06468          if (!res)
06469             res = ast_play_and_wait(chan, "vm-message");
06470          if (!res)
06471             res = ast_play_and_wait(chan, "vm-INBOXs");
06472       }
06473       else {
06474          if (!res)
06475             res = ast_play_and_wait(chan, "vm-messages");
06476          if (!res)
06477             res = ast_play_and_wait(chan, "vm-INBOX");
06478       }
06479       if (vms->oldmessages && !res)
06480          res = ast_play_and_wait(chan, "vm-and");
06481    }
06482    if (vms->oldmessages) {
06483       if (!res)
06484          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06485       if (vms->oldmessages == 1) {
06486          if (!res)
06487             res = ast_play_and_wait(chan, "vm-message");
06488          if (!res)
06489             res = ast_play_and_wait(chan, "vm-Olds");
06490       }
06491       else {
06492          if (!res)
06493       res = ast_play_and_wait(chan, "vm-messages");
06494          if (!res)
06495             res = ast_play_and_wait(chan, "vm-Old");
06496       }
06497    }
06498    return res;
06499 }

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

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

06265 {
06266    /* Introduce messages they have */
06267    int res;
06268 
06269    res = ast_play_and_wait(chan, "vm-youhave");
06270    if (res)
06271       return res;
06272 
06273    if (!vms->oldmessages && !vms->newmessages) {
06274       res = ast_play_and_wait(chan, "vm-no");
06275       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06276       return res;
06277    }
06278 
06279    if (vms->newmessages) {
06280       if ((vms->newmessages == 1)) {
06281          res = ast_play_and_wait(chan, "digits/ett");
06282          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
06283          res = res ? res : ast_play_and_wait(chan, "vm-message");
06284       } else {
06285          res = say_and_wait(chan, vms->newmessages, chan->language);
06286          res = res ? res : ast_play_and_wait(chan, "vm-nya");
06287          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06288       }
06289       if (!res && vms->oldmessages)
06290          res = ast_play_and_wait(chan, "vm-and");
06291    }
06292    if (!res && vms->oldmessages) {
06293       if (vms->oldmessages == 1) {
06294          res = ast_play_and_wait(chan, "digits/ett");
06295          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
06296          res = res ? res : ast_play_and_wait(chan, "vm-message");
06297       } else {
06298          res = say_and_wait(chan, vms->oldmessages, chan->language);
06299          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
06300          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06301       }
06302    }
06303 
06304    return res;
06305 }

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

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

02191 {
02192    switch (ast_lock_path(path)) {
02193    case AST_LOCK_TIMEOUT:
02194       return -1;
02195    default:
02196       return 0;
02197    }
02198 }

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

Definition at line 918 of file app_voicemail.c.

References VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

00919 {
00920    FILE *p = NULL;
00921    int pfd = mkstemp(template);
00922    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
00923    if (pfd > -1) {
00924       p = fdopen(pfd, "w+");
00925       if (!p) {
00926          close(pfd);
00927          pfd = -1;
00928       }
00929    }
00930    return p;
00931 }

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 6817 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().

06818 {
06819    int cmd = 0;
06820    int duration = 0;
06821    int tries = 0;
06822    char newpassword[80] = "";
06823    char newpassword2[80] = "";
06824    char prefile[PATH_MAX] = "";
06825    unsigned char buf[256];
06826    int bytes=0;
06827 
06828    if (ast_adsi_available(chan)) {
06829       bytes += adsi_logo(buf + bytes);
06830       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
06831       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06832       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06833       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06834       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06835    }
06836 
06837    /* First, have the user change their password 
06838       so they won't get here again */
06839    for (;;) {
06840       newpassword[1] = '\0';
06841       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06842       if (cmd == '#')
06843          newpassword[0] = '\0';
06844       if (cmd < 0 || cmd == 't' || cmd == '#')
06845          return cmd;
06846       cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
06847       if (cmd < 0 || cmd == 't' || cmd == '#')
06848          return cmd;
06849       newpassword2[1] = '\0';
06850       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06851       if (cmd == '#')
06852          newpassword2[0] = '\0';
06853       if (cmd < 0 || cmd == 't' || cmd == '#')
06854          return cmd;
06855       cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
06856       if (cmd < 0 || cmd == 't' || cmd == '#')
06857          return cmd;
06858       if (!strcmp(newpassword, newpassword2))
06859          break;
06860       ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
06861       cmd = ast_play_and_wait(chan, "vm-mismatch");
06862       if (++tries == 3)
06863          return -1;
06864    }
06865    if (ast_strlen_zero(ext_pass_cmd)) 
06866       vm_change_password(vmu,newpassword);
06867    else 
06868       vm_change_password_shell(vmu,newpassword);
06869    if (option_debug > 2)
06870       ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
06871    cmd = ast_play_and_wait(chan,"vm-passchanged");
06872 
06873    /* If forcename is set, have the user record their name */  
06874    if (ast_test_flag(vmu, VM_FORCENAME)) {
06875       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06876       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06877          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06878          if (cmd < 0 || cmd == 't' || cmd == '#')
06879             return cmd;
06880       }
06881    }
06882 
06883    /* If forcegreetings is set, have the user record their greetings */
06884    if (ast_test_flag(vmu, VM_FORCEGREET)) {
06885       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06886       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06887          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06888          if (cmd < 0 || cmd == 't' || cmd == '#')
06889             return cmd;
06890       }
06891 
06892       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06893       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06894          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06895          if (cmd < 0 || cmd == 't' || cmd == '#')
06896             return cmd;
06897       }
06898    }
06899 
06900    return cmd;
06901 }

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 6903 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().

06904 {
06905    int cmd = 0;
06906    int retries = 0;
06907    int duration = 0;
06908    char newpassword[80] = "";
06909    char newpassword2[80] = "";
06910    char prefile[PATH_MAX] = "";
06911    unsigned char buf[256];
06912    int bytes=0;
06913 
06914    if (ast_adsi_available(chan))
06915    {
06916       bytes += adsi_logo(buf + bytes);
06917       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
06918       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06919       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06920       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06921       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06922    }
06923    while ((cmd >= 0) && (cmd != 't')) {
06924       if (cmd)
06925          retries = 0;
06926       switch (cmd) {
06927       case '1':
06928          snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06929          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06930          break;
06931       case '2': 
06932          snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06933          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06934          break;
06935       case '3': 
06936          snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06937          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06938          break;
06939       case '4': 
06940          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
06941          break;
06942       case '5':
06943          if (vmu->password[0] == '-') {
06944             cmd = ast_play_and_wait(chan, "vm-no");
06945             break;
06946          }
06947          newpassword[1] = '\0';
06948          newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06949          if (cmd == '#')
06950             newpassword[0] = '\0';
06951          else {
06952             if (cmd < 0)
06953                break;
06954             if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
06955                break;
06956             }
06957          }
06958          newpassword2[1] = '\0';
06959          newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06960          if (cmd == '#')
06961             newpassword2[0] = '\0';
06962          else {
06963             if (cmd < 0)
06964                break;
06965 
06966             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#")) < 0) {
06967                break;
06968             }
06969          }
06970          if (strcmp(newpassword, newpassword2)) {
06971             ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
06972             cmd = ast_play_and_wait(chan, "vm-mismatch");
06973             break;
06974          }
06975          if (ast_strlen_zero(ext_pass_cmd)) 
06976             vm_change_password(vmu,newpassword);
06977          else 
06978             vm_change_password_shell(vmu,newpassword);
06979          if (option_debug > 2)
06980             ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
06981          cmd = ast_play_and_wait(chan,"vm-passchanged");
06982          break;
06983       case '*': 
06984          cmd = 't';
06985          break;
06986       default: 
06987          cmd = 0;
06988          snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06989          RETRIEVE(prefile, -1, vmu);
06990          if (ast_fileexists(prefile, NULL, NULL))
06991             cmd = ast_play_and_wait(chan, "vm-tmpexists");
06992          DISPOSE(prefile, -1);
06993          if (!cmd)
06994             cmd = ast_play_and_wait(chan, "vm-options");
06995          if (!cmd)
06996             cmd = ast_waitfordigit(chan,6000);
06997          if (!cmd)
06998             retries++;
06999          if (retries > 3)
07000             cmd = 't';
07001       }
07002    }
07003    if (cmd == 't')
07004       cmd = 0;
07005    return cmd;
07006 }

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

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

05879 {
05880    int cmd;
05881 
05882    if (!strncasecmp(chan->language, "it", 2) || !strncasecmp(chan->language, "es", 2) || !strncasecmp(chan->language, "fr", 2) || !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, French or Portuguese syntax */
05883       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
05884       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05885    } else if (!strncasecmp(chan->language, "gr", 2)){
05886       return vm_play_folder_name_gr(chan, mbox);
05887    } else if (!strncasecmp(chan->language, "pl", 2)){
05888       return vm_play_folder_name_pl(chan, mbox);
05889    } else if (!strncasecmp(chan->language, "ua", 2)){  /* Ukrainian syntax */
05890       return vm_play_folder_name_ua(chan, mbox);
05891    } else if (!strcasecmp(chan->language, "he")){  /* Hebrew syntax */
05892       cmd = ast_play_and_wait(chan, mbox);
05893       return cmd;
05894    } else {  /* Default English */
05895       cmd = ast_play_and_wait(chan, mbox);
05896       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
05897    }
05898 }

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

Definition at line 5831 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05832 {
05833    int cmd;
05834    char *buf;
05835 
05836    buf = alloca(strlen(mbox)+2); 
05837    strcpy(buf, mbox);
05838    strcat(buf,"s");
05839 
05840    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
05841       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
05842       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
05843    } else {
05844       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
05845       return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
05846    }
05847 }

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

Definition at line 5849 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05850 {
05851    int cmd;
05852 
05853    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
05854       if (!strcasecmp(mbox, "vm-INBOX"))
05855          cmd = ast_play_and_wait(chan, "vm-new-e");
05856       else
05857          cmd = ast_play_and_wait(chan, "vm-old-e");
05858       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05859    } else {
05860       cmd = ast_play_and_wait(chan, "vm-messages");
05861       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05862    }
05863 }

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

Definition at line 5865 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05866 {
05867    int cmd;
05868 
05869    if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")){
05870       cmd = ast_play_and_wait(chan, "vm-messages");
05871       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05872    } else {
05873       cmd = ast_play_and_wait(chan, mbox);
05874       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05875    }
05876 }

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 7008 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().

07009 {
07010    int res;
07011    int cmd = 0;
07012    int retries = 0;
07013    int duration = 0;
07014    char prefile[PATH_MAX] = "";
07015    unsigned char buf[256];
07016    char dest[PATH_MAX];
07017    int bytes = 0;
07018 
07019    if (ast_adsi_available(chan)) {
07020       bytes += adsi_logo(buf + bytes);
07021       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
07022       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
07023       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
07024       bytes += ast_adsi_voice_mode(buf + bytes, 0);
07025       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
07026    }
07027 
07028    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
07029    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
07030       ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
07031       return -1;
07032    }
07033    while ((cmd >= 0) && (cmd != 't')) {
07034       if (cmd)
07035          retries = 0;
07036       RETRIEVE(prefile, -1, vmu);
07037       if (ast_fileexists(prefile, NULL, NULL) <= 0) {
07038          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07039          cmd = 't';  
07040       } else {
07041          switch (cmd) {
07042          case '1':
07043             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07044             break;
07045          case '2':
07046             DELETE(prefile, -1, prefile, vmu);
07047             ast_play_and_wait(chan, "vm-tempremoved");
07048             cmd = 't';  
07049             break;
07050          case '*': 
07051             cmd = 't';
07052             break;
07053          default:
07054             cmd = ast_play_and_wait(chan,
07055                ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
07056                   "vm-tempgreeting2" : "vm-tempgreeting");
07057             if (!cmd)
07058                cmd = ast_waitfordigit(chan,6000);
07059             if (!cmd)
07060                retries++;
07061             if (retries > 3)
07062                cmd = 't';
07063          }
07064       }
07065       DISPOSE(prefile, -1);
07066    }
07067    if (cmd == 't')
07068       cmd = 0;
07069    return cmd;
07070 }

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

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

08032 {
08033    struct ast_module_user *u;
08034    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
08035    struct ast_vm_user vmus;
08036    char *options = NULL;
08037    int silent = 0, skipuser = 0;
08038    int res = -1;
08039 
08040    u = ast_module_user_add(chan);
08041    
08042    if (s) {
08043       s = ast_strdupa(s);
08044       user = strsep(&s, "|");
08045       options = strsep(&s, "|");
08046       if (user) {
08047          s = user;
08048          user = strsep(&s, "@");
08049          context = strsep(&s, "");
08050          if (!ast_strlen_zero(user))
08051             skipuser++;
08052          ast_copy_string(mailbox, user, sizeof(mailbox));
08053       }
08054    }
08055 
08056    if (options) {
08057       silent = (strchr(options, 's')) != NULL;
08058    }
08059 
08060    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
08061       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
08062       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
08063       ast_play_and_wait(chan, "auth-thankyou");
08064       res = 0;
08065    }
08066 
08067    ast_module_user_remove(u);
08068    return res;
08069 }

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

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

03068 {
03069    const struct vm_zone *z = NULL;
03070    time_t t = time(NULL);
03071 
03072    /* Does this user have a timezone specified? */
03073    if (!ast_strlen_zero(vmu->zonetag)) {
03074       /* Find the zone in the list */
03075       AST_LIST_LOCK(&zones);
03076       AST_LIST_TRAVERSE(&zones, z, list) {
03077          if (!strcmp(z->name, vmu->zonetag))
03078             break;
03079       }
03080       AST_LIST_UNLOCK(&zones);
03081    }
03082    ast_localtime(&t, tm, z ? z->timezone : NULL);
03083    return tm;
03084 }

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

Definition at line 5369 of file app_voicemail.c.

References ast_control_streamfile().

05370 {
05371    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
05372 }

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

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

05362 {
05363    int res;
05364    if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0) 
05365       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
05366    return res;
05367 }


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 = "6989f2ec67f8497e38c12890500c525b" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 9318 of file app_voicemail.c.

char* addesc = "Comedian Mail" [static]

Definition at line 454 of file app_voicemail.c.

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

Definition at line 576 of file app_voicemail.c.

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

Definition at line 577 of file app_voicemail.c.

int adsiver = 1 [static]

Definition at line 578 of file app_voicemail.c.

char* app = "VoiceMail" [static]

Definition at line 530 of file app_voicemail.c.

char* app2 = "VoiceMailMain" [static]

Definition at line 533 of file app_voicemail.c.

char* app3 = "MailboxExists" [static]

Definition at line 535 of file app_voicemail.c.

char* app4 = "VMAuthenticate" [static]

Definition at line 536 of file app_voicemail.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 9318 of file app_voicemail.c.

char callcontext[AST_MAX_CONTEXT] [static]

Definition at line 561 of file app_voicemail.c.

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

Definition at line 574 of file app_voicemail.c.

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static]

Definition at line 564 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 8173 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 8178 of file app_voicemail.c.

struct ast_cli_entry cli_voicemail[] [static]

Definition at line 8183 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char* descrip_vm [static]

Definition at line 459 of file app_voicemail.c.

char* descrip_vm_box_exists [static]

Definition at line 505 of file app_voicemail.c.

char* descrip_vmain [static]

Definition at line 487 of file app_voicemail.c.

char* descrip_vmauthenticate [static]

Definition at line 519 of file app_voicemail.c.

char dialcontext[AST_MAX_CONTEXT] [static]

Definition at line 560 of file app_voicemail.c.

Referenced by directory_exec().

char* emailbody = NULL [static]

Definition at line 567 of file app_voicemail.c.

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

Definition at line 579 of file app_voicemail.c.

char* emailsubject = NULL [static]

Definition at line 568 of file app_voicemail.c.

char emailtitle[100] [static]

Definition at line 573 of file app_voicemail.c.

char exitcontext[AST_MAX_CONTEXT] [static]

Definition at line 562 of file app_voicemail.c.

Referenced by conf_run().

char ext_pass_cmd[128] [static]

Definition at line 440 of file app_voicemail.c.

char externnotify[160] [static]

Definition at line 546 of file app_voicemail.c.

char fromstring[100] [static]

Definition at line 571 of file app_voicemail.c.

struct ast_flags globalflags = {0} [static]

Definition at line 556 of file app_voicemail.c.

char mailcmd[160] [static]

Definition at line 545 of file app_voicemail.c.

int maxgreet [static]

Definition at line 552 of file app_voicemail.c.

int maxlogins [static]

Definition at line 554 of file app_voicemail.c.

int maxmsg [static]

Definition at line 542 of file app_voicemail.c.

int maxsilence [static]

Definition at line 541 of file app_voicemail.c.

Referenced by ast_record_review().

int my_umask [static]

Definition at line 442 of file app_voicemail.c.

char* pagerbody = NULL [static]

Definition at line 569 of file app_voicemail.c.

char pagerfromstring[100] [static]

Definition at line 572 of file app_voicemail.c.

char* pagersubject = NULL [static]

Definition at line 570 of file app_voicemail.c.

int saydurationminfo [static]

Definition at line 558 of file app_voicemail.c.

char serveremail[80] [static]

Definition at line 544 of file app_voicemail.c.

int silencethreshold = 128 [static]

Definition at line 543 of file app_voicemail.c.

int skipms [static]

Definition at line 553 of file app_voicemail.c.

Referenced by controlplayback_exec(), and handle_controlstreamfile().

struct ast_smdi_interface* smdi_iface = NULL [static]

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

char* synopsis_vm_box_exists [static]

Initial value:

"Check to see if Voicemail mailbox exists"

Definition at line 502 of file app_voicemail.c.

char* synopsis_vmain [static]

Initial value:

"Check Voicemail messages"

Definition at line 484 of file app_voicemail.c.

char* synopsis_vmauthenticate [static]

Initial value:

"Authenticate with Voicemail passwords"

Definition at line 516 of file app_voicemail.c.

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

Definition at line 452 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 236 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 438 of file app_voicemail.c.

char vmfmts[80] [static]

Definition at line 548 of file app_voicemail.c.

int vmmaxmessage [static]

Definition at line 551 of file app_voicemail.c.

int vmminmessage [static]

Definition at line 550 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 8071 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 8075 of file app_voicemail.c.

double volgain [static]

Definition at line 549 of file app_voicemail.c.

char zonetag[80] [static]

Definition at line 540 of file app_voicemail.c.

Referenced by build_peer().


Generated on Thu Oct 8 00:59:19 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7