Comedian Mail - Voicemail System. More...
#include "asterisk.h"
#include "asterisk/paths.h"
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include "asterisk/logger.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/module.h"
#include "asterisk/adsi.h"
#include "asterisk/app.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/stringfields.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj2.h"
#include "asterisk/event.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
Go to the source code of this file.
Data Structures | |
struct | ast_vm_user |
struct | baseio |
struct | inprocess |
struct | leave_vm_options |
Options for leaving voicemail with the voicemail() application. More... | |
struct | mwi_sub |
An MWI subscription. More... | |
struct | mwi_sub_task |
struct | vm_state |
struct | vm_zone |
Defines | |
#define | ASTERISK_USERNAME "asterisk" |
#define | BASELINELEN 72 |
#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 | DATA_EXPORT_VM_USERS(USER) |
#define | DATA_EXPORT_VM_ZONES(ZONE) |
#define | DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
#define | DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
#define | DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
#define | DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
#define | DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
#define | DEFAULT_POLL_FREQ 30 |
#define | DELETE(a, b, c, d) (vm_delete(c)) |
#define | DISPOSE(a, b) |
#define | ENDL "\n" |
#define | ERROR_LOCK_PATH -100 |
#define | EXISTS(a, b, c, d) (ast_fileexists(c,NULL,d) > 0) |
#define | HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
#define | HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
#define | INTRO "vm-intro" |
#define | MAX_DATETIME_FORMAT 512 |
#define | MAX_NUM_CID_CONTEXTS 10 |
#define | MAXMSG 100 |
#define | MAXMSGLIMIT 9999 |
#define | MINPASSWORD 0 |
#define | OPERATOR_EXIT 300 |
#define | PWDCHANGE_EXTERNAL (1 << 2) |
#define | PWDCHANGE_INTERNAL (1 << 1) |
#define | RENAME(a, b, c, d, e, f, g, h) (rename_file(g,h)); |
#define | RETRIEVE(a, b, c, d) |
#define | SENDMAIL "/usr/sbin/sendmail -t" |
#define | SMDI_MWI_WAIT_TIMEOUT 1000 |
#define | STORE(a, b, c, d, e, f, g, h, i, j) |
#define | tdesc "Comedian Mail (Voicemail System)" |
#define | VALID_DTMF "1234567890*#" |
#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_FWDURGAUTO (1 << 18) |
#define | VM_MESSAGEWRAP (1 << 17) |
#define | VM_MOVEHEARD (1 << 16) |
#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 | VMSTATE_MAX_MSG_ARRAY 256 |
#define | VOICEMAIL_CONFIG "voicemail.conf" |
#define | VOICEMAIL_DIR_MODE 0777 |
#define | VOICEMAIL_FILE_MODE 0666 |
Enumerations | |
enum | vm_box { NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER, NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER, NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER } |
enum | vm_option_args { OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3, OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3, OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3 } |
enum | vm_option_flags { OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9), OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9), OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9) } |
enum | vm_passwordlocation { OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2, OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2, OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2 } |
Functions | |
static int | __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit) |
static int | acf_mailbox_exists (struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len) |
static int | actual_load_config (int reload, struct ast_config *cfg, struct ast_config *ucfg) |
static int | add_email_attachment (FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum) |
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) |
The advanced options within a message. | |
static int | append_mailbox (const char *context, const char *box, const char *data) |
static void | apply_option (struct ast_vm_user *vmu, const char *var, const char *value) |
Sets a a specific property value. | |
static void | apply_options (struct ast_vm_user *vmu, const char *options) |
Destructively Parse options and apply. | |
static void | apply_options_full (struct ast_vm_user *retval, struct ast_variable *var) |
Loads the options specific to a voicemail user. | |
AST_APP_OPTIONS (vm_app_options,{AST_APP_OPTION('s', OPT_SILENT), AST_APP_OPTION('b', OPT_BUSY_GREETING), AST_APP_OPTION('u', OPT_UNAVAIL_GREETING), AST_APP_OPTION_ARG('g', OPT_RECORDGAIN, OPT_ARG_RECORDGAIN), AST_APP_OPTION_ARG('d', OPT_DTMFEXIT, OPT_ARG_DTMFEXIT), AST_APP_OPTION('p', OPT_PREPEND_MAILBOX), AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER), AST_APP_OPTION('U', OPT_MESSAGE_Urgent),}) | |
AST_DATA_STRUCTURE (vm_zone, DATA_EXPORT_VM_ZONES) | |
AST_DATA_STRUCTURE (ast_vm_user, DATA_EXPORT_VM_USERS) | |
static | AST_LIST_HEAD_STATIC (zones, vm_zone) |
static | AST_LIST_HEAD_STATIC (users, ast_vm_user) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,.load=load_module,.unload=unload_module,.reload=reload,.nonoptreq="res_adsi,res_smdi",) | |
AST_MUTEX_DEFINE_STATIC (poll_lock) | |
static | AST_RWLIST_HEAD_STATIC (mwi_subs, mwi_sub) |
static const char * | ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *start, 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 const char * | ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from) |
Wraps a character sequence in double quotes, escaping occurences of quotes within the string. | |
AST_TEST_DEFINE (test_voicemail_vmuser) | |
static int | base_encode (char *filename, FILE *so) |
Performs a base 64 encode algorithm on the contents of a File. | |
static int | change_password_realtime (struct ast_vm_user *vmu, const char *password) |
Performs a change of the voicemail passowrd in the realtime engine. | |
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 | check_password (struct ast_vm_user *vmu, char *password) |
Check that password meets minimum required length. | |
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) |
Utility function to copy a file. | |
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, const char *flag) |
Copies a message from one mailbox to another. | |
static void | copy_plain_file (char *frompath, char *topath) |
Copies a voicemail information (envelope) file. | |
static int | count_messages (struct ast_vm_user *vmu, char *dir) |
Find all .txt files - even if they are not in sequence from 0000. | |
static int | create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder) |
basically mkdir -p $dest/$context/$ext/$folder | |
static int | dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context) |
static struct ast_vm_user * | find_or_create (const char *context, const char *box) |
static struct ast_vm_user * | find_user (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the users file or the realtime engine. | |
static struct ast_vm_user * | find_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the realtime engine. | |
static int | forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int is_new_message, signed char record_gain, int urgent) |
Sends a voicemail message to a mailbox recipient. | |
static void | free_user (struct ast_vm_user *vmu) |
static void | free_vm_users (void) |
Free the users structure. | |
static void | free_vm_zones (void) |
Free the zones structure. | |
static void | free_zone (struct vm_zone *z) |
static int | get_date (char *s, int len) |
Gets the current date and time, as formatted string. | |
static int | get_folder (struct ast_channel *chan, int start) |
get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized | |
static int | get_folder2 (struct ast_channel *chan, char *fn, int start) |
plays a prompt and waits for a keypress. | |
static int | get_folder_by_name (const char *name) |
static int | handle_subscribe (void *datap) |
static int | handle_unsubscribe (void *datap) |
static char * | handle_voicemail_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Reload voicemail configuration from the CLI. | |
static char * | handle_voicemail_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail users in the CLI. | |
static char * | handle_voicemail_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail zones in the CLI. | |
static int | has_voicemail (const char *mailbox, const char *folder) |
Determines if the given folder has messages. | |
static int | inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs) |
static int | inboxcount2 (const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs) |
static int | inbuf (struct baseio *bio, FILE *fi) |
utility used by inchar(), for base_encode() | |
static int | inchar (struct baseio *bio, FILE *fi) |
utility used by base_encode() | |
static int | inprocess_cmp_fn (void *obj, void *arg, int flags) |
static int | inprocess_count (const char *context, const char *mailbox, int delta) |
static int | inprocess_hash_fn (const void *obj, const int flags) |
static int | invent_message (struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes) |
static int | is_valid_dtmf (const char *key) |
Determines if a DTMF key entered is valid. | |
static int | last_message_index (struct ast_vm_user *vmu, char *dir) |
Determines the highest message number in use for a given user and mailbox folder. | |
static int | leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options) |
Prompts the user and records a voicemail to a mailbox. | |
static int | load_config (int reload) |
static int | load_module (void) |
static int | make_dir (char *dest, int len, const char *context, const char *ext, const char *folder) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static void | make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag) |
Creates the email file to be sent to indicate a new voicemail exists for a user. | |
static int | make_file (char *dest, const int len, const char *dir, const int num) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static int | manager_list_voicemail_users (struct mansession *s, const struct message *m) |
Manager list voicemail users command. | |
static void * | mb_poll_thread (void *data) |
static const char * | mbox (struct ast_vm_user *vmu, int id) |
static int | messagecount (const char *context, const char *mailbox, const char *folder) |
static void | mwi_sub_destroy (struct mwi_sub *mwi_sub) |
static void | mwi_sub_event_cb (const struct ast_event *event, void *userdata) |
static void | mwi_unsub_event_cb (const struct ast_event *event, void *userdata) |
static int | notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag) |
Sends email notification that a user has a new voicemail waiting for them. | |
static int | ochar (struct baseio *bio, int c, FILE *so) |
utility used by base_encode() | |
static int | open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box) |
static int | play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, 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, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag) |
static void | poll_subscribed_mailbox (struct mwi_sub *mwi_sub) |
static void | poll_subscribed_mailboxes (void) |
static void | populate_defaults (struct ast_vm_user *vmu) |
Sets default voicemail system options to a voicemail user. | |
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, const char *category, const char *flag) |
static void | queue_mwi_event (const char *box, int urgent, int new, int old) |
static void | read_password_from_file (const char *secretfn, char *password, int passwordlen) |
static int | reload (void) |
static void | rename_file (char *sfn, char *dfn) |
Renames a message in a mailbox folder. | |
static int | resequence_mailbox (struct ast_vm_user *vmu, char *dir, int stopcount) |
static int | reset_user_pw (const char *context, const char *mailbox, const char *newpass) |
Resets a user password to a specified password. | |
static void | run_externnotify (char *context, char *extension, const char *flag) |
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 | sayname (struct ast_channel *chan, const char *mailbox, const char *context) |
static int | sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag) |
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, const char *flag) |
static char * | show_users_realtime (int fd, const char *context) |
static void | start_poll_thread (void) |
static void | stop_poll_thread (void) |
static char * | strip_control_and_high (const char *input, char *buf, size_t buflen) |
Strips control and non 7-bit clean characters from input string. | |
static const char * | substitute_escapes (const char *value) |
static int | unload_module (void) |
static int | valid_config (const struct ast_config *cfg) |
Check if configuration file is valid. | |
static int | vm_allocate_dh (struct vm_state *vms, struct ast_vm_user *vmu, int count_msg) |
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 max_logins, int silent) |
static int | vm_box_exists (struct ast_channel *chan, const char *data) |
static int | vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Top level method to invoke the language variant vm_browse_messages_XX function. | |
static int | vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Default English syntax for 'You have N messages' greeting. | |
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) |
Common LATIN languages syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_vi (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Vietnamese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_zh (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Chinese (Taiwan)syntax for 'You have N messages' greeting. | |
static void | vm_change_password (struct ast_vm_user *vmu, const char *newpassword) |
The handler for the change password option. | |
static void | vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword) |
static char * | vm_check_password_shell (char *command, char *buf, size_t len) |
static int | vm_delete (char *file) |
Removes the voicemail sound and information file. | |
static int | vm_exec (struct ast_channel *chan, const char *data) |
static int | vm_execmain (struct ast_channel *chan, const char *data) |
static int | vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts, char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag) |
presents the option to prepend to an existing message when forwarding it. | |
static int | vm_instructions (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_en (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_zh (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | vm_intro_cs (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_de (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_en (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_es (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_fr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_gr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_he (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_it (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[]) |
static int | vm_intro_nl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_no (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_se (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_vi (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_zh (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_lock_path (const char *path) |
Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason. | |
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 *box) |
static int | vm_play_folder_name_pl (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_ua (struct ast_channel *chan, char *box) |
static int | vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
The handler for 'record a temporary greeting'. | |
static int | vm_users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static int | vm_users_data_provider_get_helper (const struct ast_data_search *search, struct ast_data *data_root, struct ast_vm_user *user) |
static int | vmauthenticate (struct ast_channel *chan, const char *data) |
static int | vmsayname_exec (struct ast_channel *chan, const char *data) |
static struct ast_tm * | vmu_tm (const struct ast_vm_user *vmu, struct ast_tm *tm) |
fill in *tm for current time according to the proper timezone, if any. | |
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) |
static int | write_password_to_file (const char *secretfn, const char *password) |
Variables | |
static char * | addesc = "Comedian Mail" |
static unsigned char | adsifdn [4] = "\x00\x00\x00\x0F" |
static unsigned char | adsisec [4] = "\x9B\xDB\xF7\xAC" |
static int | adsiver = 1 |
static char * | app = "VoiceMail" |
static char * | app2 = "VoiceMailMain" |
static char * | app3 = "MailboxExists" |
static char * | app4 = "VMAuthenticate" |
static char | callcontext [AST_MAX_CONTEXT] = "" |
static char | charset [32] = "ISO-8859-1" |
static char | cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64] |
static struct ast_cli_entry | cli_voicemail [] |
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 | exitcontext [AST_MAX_CONTEXT] = "" |
static char | ext_pass_check_cmd [128] |
static char | ext_pass_cmd [128] |
static char | externnotify [160] |
static char | fromstring [100] |
static struct ast_flags | globalflags = {0} |
struct ao2_container * | inprocess_container |
static char | listen_control_forward_key [12] |
static char | listen_control_pause_key [12] |
static char | listen_control_restart_key [12] |
static char | listen_control_reverse_key [12] |
static char | listen_control_stop_key [12] |
static char | locale [20] |
static struct ast_custom_function | mailbox_exists_acf |
static const char *const | mailbox_folders [] |
static char | mailcmd [160] |
static int | maxdeletedmsg |
static int | maxgreet |
static int | maxlogins |
static int | maxmsg |
static int | maxsilence |
static int | minpassword |
static struct ast_event_sub * | mwi_sub_sub |
static struct ast_taskprocessor * | mwi_subscription_tps |
static struct ast_event_sub * | mwi_unsub_sub |
static int | my_umask |
static char * | pagerbody = NULL |
static char | pagerdateformat [32] = "%A, %B %d, %Y at %r" |
static char | pagerfromstring [100] |
static char * | pagersubject = NULL |
static int | passwordlocation |
static ast_cond_t | poll_cond = PTHREAD_COND_INITIALIZER |
static unsigned int | poll_freq |
static unsigned int | poll_mailboxes |
static pthread_t | poll_thread = AST_PTHREADT_NULL |
static unsigned char | poll_thread_run |
static int | pwdchange = PWDCHANGE_INTERNAL |
static int | saydurationminfo |
static char * | sayname_app = "VMSayName" |
static char | serveremail [80] |
static int | silencethreshold = 128 |
static int | skipms |
static struct ast_smdi_interface * | smdi_iface = NULL |
static char | userscontext [AST_MAX_EXTENSION] = "default" |
static struct ast_data_entry | vm_data_providers [] |
static char | vm_invalid_password [80] = "vm-invalid-password" |
static char | vm_mismatch [80] = "vm-mismatch" |
static char | vm_newpassword [80] = "vm-newpassword" |
static char | vm_passchanged [80] = "vm-passchanged" |
static char | vm_password [80] = "vm-password" |
static char | vm_pls_try_again [80] = "vm-pls-try-again" |
static char | vm_prepend_timeout [80] = "vm-then-pound" |
static char | vm_reenterpassword [80] = "vm-reenterpassword" |
static char | VM_SPOOL_DIR [PATH_MAX] |
static struct ast_data_handler | vm_users_data_provider |
static char | vmfmts [80] |
static int | vmmaxsecs |
static int | vmminsecs |
static double | volgain |
static char | zonetag [80] |
Comedian Mail - Voicemail System.
Definition in file app_voicemail.c.
#define ASTERISK_USERNAME "asterisk" |
Definition at line 430 of file app_voicemail.c.
#define BASELINELEN 72 |
Definition at line 453 of file app_voicemail.c.
Referenced by ochar().
#define BASEMAXINLINE 256 |
Definition at line 454 of file app_voicemail.c.
Referenced by base_encode(), and inbuf().
#define CHUNKSIZE 65536 |
Definition at line 427 of file app_voicemail.c.
#define COMMAND_TIMEOUT 5000 |
Definition at line 423 of file app_voicemail.c.
#define COPY | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (copy_plain_file(g,h)); |
Definition at line 741 of file app_voicemail.c.
Referenced by copy_message(), and save_to_folder().
#define DATA_EXPORT_VM_USERS | ( | USER | ) |
Definition at line 11296 of file app_voicemail.c.
#define DATA_EXPORT_VM_ZONES | ( | ZONE | ) |
ZONE(vm_zone, name, AST_DATA_STRING) \ ZONE(vm_zone, timezone, AST_DATA_STRING) \ ZONE(vm_zone, msg_format, AST_DATA_STRING)
Definition at line 11323 of file app_voicemail.c.
#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
Definition at line 435 of file app_voicemail.c.
Referenced by actual_load_config().
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
Definition at line 437 of file app_voicemail.c.
Referenced by actual_load_config().
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
Definition at line 438 of file app_voicemail.c.
Referenced by actual_load_config().
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
Definition at line 436 of file app_voicemail.c.
Referenced by actual_load_config().
#define DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
Definition at line 439 of file app_voicemail.c.
Referenced by actual_load_config().
#define DEFAULT_POLL_FREQ 30 |
By default, poll every 30 seconds
Definition at line 811 of file app_voicemail.c.
Referenced by actual_load_config().
#define DELETE | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (vm_delete(c)) |
Definition at line 742 of file app_voicemail.c.
Referenced by close_mailbox(), notify_new_message(), play_record_review(), and vm_tempgreeting().
#define DISPOSE | ( | a, | |||
b | ) |
Definition at line 737 of file app_voicemail.c.
Referenced by advanced_options(), forward_message(), invent_message(), leave_voicemail(), notify_new_message(), play_message(), play_record_review(), sayname(), vm_intro(), vm_options(), and vm_tempgreeting().
#define ENDL "\n" |
Definition at line 458 of file app_voicemail.c.
Referenced by add_email_attachment(), base_encode(), make_email_file(), ochar(), and sendpage().
#define ERROR_LOCK_PATH -100 |
Definition at line 483 of file app_voicemail.c.
#define EXISTS | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 739 of file app_voicemail.c.
Referenced by close_mailbox(), copy_message(), resequence_mailbox(), and save_to_folder().
#define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
Referenced by handle_voicemail_show_users().
#define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
Referenced by handle_voicemail_show_zones().
#define INTRO "vm-intro" |
Definition at line 446 of file app_voicemail.c.
Referenced by leave_voicemail(), play_record_review(), and vm_forwardoptions().
#define MAX_DATETIME_FORMAT 512 |
Definition at line 461 of file app_voicemail.c.
#define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 462 of file app_voicemail.c.
#define MAXMSG 100 |
Definition at line 448 of file app_voicemail.c.
Referenced by actual_load_config(), and apply_option().
#define MAXMSGLIMIT 9999 |
Definition at line 449 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), and last_message_index().
#define MINPASSWORD 0 |
Default minimum mailbox password length
Definition at line 451 of file app_voicemail.c.
Referenced by actual_load_config().
#define OPERATOR_EXIT 300 |
Definition at line 484 of file app_voicemail.c.
Referenced by leave_voicemail(), vm_exec(), and vm_execmain().
#define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 754 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
#define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 753 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
#define RENAME | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (rename_file(g,h)); |
Definition at line 740 of file app_voicemail.c.
Referenced by close_mailbox(), leave_voicemail(), resequence_mailbox(), and save_to_folder().
#define RETRIEVE | ( | a, | |||
b, | |||||
c, | |||||
d | ) |
Definition at line 736 of file app_voicemail.c.
Referenced by advanced_options(), forward_message(), invent_message(), leave_voicemail(), notify_new_message(), play_message(), sayname(), vm_intro(), vm_options(), and vm_tempgreeting().
#define SENDMAIL "/usr/sbin/sendmail -t" |
Definition at line 444 of file app_voicemail.c.
#define SMDI_MWI_WAIT_TIMEOUT 1000 |
Definition at line 421 of file app_voicemail.c.
Referenced by run_externnotify().
#define STORE | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h, | |||||
i, | |||||
j | ) |
Definition at line 738 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 763 of file app_voicemail.c.
#define VALID_DTMF "1234567890*#" |
Definition at line 440 of file app_voicemail.c.
Referenced by is_valid_dtmf().
#define VM_ALLOCED (1 << 13) |
Structure was malloc'ed, instead of placed in a return (usually static) buffer
Definition at line 477 of file app_voicemail.c.
Referenced by AST_TEST_DEFINE(), find_user(), find_user_realtime(), free_user(), and free_vm_users().
#define VM_ATTACH (1 << 11) |
Attach message to voicemail notifications?
Definition at line 475 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), forward_message(), manager_list_voicemail_users(), notify_new_message(), and sendmail().
#define VM_DELETE (1 << 12) |
Delete message after sending notification
Definition at line 476 of file app_voicemail.c.
Referenced by apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and notify_new_message().
#define VM_DIRECFORWARD (1 << 10) |
Permit caller to use the Directory app for selecting to which mailbox to forward a VM
Definition at line 474 of file app_voicemail.c.
Referenced by actual_load_config(), and forward_message().
#define VM_ENVELOPE (1 << 4) |
Play the envelope information (who-from, time received, etc.)
Definition at line 468 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_message().
#define VM_FORCEGREET (1 << 8) |
Have new users record their greetings
Definition at line 472 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_newuser().
#define VM_FORCENAME (1 << 7) |
Have new users record their name
Definition at line 471 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_newuser().
#define VM_FWDURGAUTO (1 << 18) |
Autoset of Urgent flag on forwarded Urgent messages set globally
Definition at line 482 of file app_voicemail.c.
Referenced by actual_load_config(), and forward_message().
#define VM_MESSAGEWRAP (1 << 17) |
Wrap around from the last message to the first, and vice-versa
Definition at line 481 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_instructions_en().
#define VM_MOVEHEARD (1 << 16) |
Move a "heard" message to Old after listening to it
Definition at line 480 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and close_mailbox().
#define VM_OPERATOR (1 << 1) |
Allow 0 to be pressed to go to 'o' extension
Definition at line 465 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), leave_voicemail(), manager_list_voicemail_users(), and play_record_review().
#define VM_PBXSKIP (1 << 9) |
Skip the [PBX] preamble in the Subject line of emails
Definition at line 473 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
#define VM_REVIEW (1 << 0) |
After recording, permit the caller to review the recording before saving
Definition at line 464 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_record_review().
#define VM_SAYCID (1 << 2) |
Repeat the CallerID info during envelope playback
Definition at line 466 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_message().
#define VM_SAYDURATION (1 << 5) |
Play the length of the message during envelope playback
Definition at line 469 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and play_message().
#define VM_SEARCH (1 << 14) |
Search all contexts for a matching mailbox
Definition at line 478 of file app_voicemail.c.
Referenced by actual_load_config(), find_or_create(), find_user(), and find_user_realtime().
#define VM_SKIPAFTERCMD (1 << 6) |
After deletion, assume caller wants to go to the next message
Definition at line 470 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_execmain().
#define VM_SVMAIL (1 << 3) |
Allow the user to compose a new VM from within VoicemailMain
Definition at line 467 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_execmain().
#define VM_TEMPGREETWARN (1 << 15) |
Remind user tempgreeting is set
Definition at line 479 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_intro().
#define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 677 of file app_voicemail.c.
#define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 429 of file app_voicemail.c.
#define VOICEMAIL_DIR_MODE 0777 |
Definition at line 425 of file app_voicemail.c.
#define VOICEMAIL_FILE_MODE 0666 |
Definition at line 426 of file app_voicemail.c.
Referenced by add_email_attachment(), copy(), leave_voicemail(), and vm_mkftemp().
enum vm_box |
Definition at line 487 of file app_voicemail.c.
00487 { 00488 NEW_FOLDER, 00489 OLD_FOLDER, 00490 WORK_FOLDER, 00491 FAMILY_FOLDER, 00492 FRIENDS_FOLDER, 00493 GREETINGS_FOLDER 00494 };
enum vm_option_args |
Definition at line 508 of file app_voicemail.c.
00508 { 00509 OPT_ARG_RECORDGAIN = 0, 00510 OPT_ARG_PLAYFOLDER = 1, 00511 OPT_ARG_DTMFEXIT = 2, 00512 /* This *must* be the last value in this enum! */ 00513 OPT_ARG_ARRAY_SIZE = 3, 00514 };
enum vm_option_flags |
Definition at line 496 of file app_voicemail.c.
00496 { 00497 OPT_SILENT = (1 << 0), 00498 OPT_BUSY_GREETING = (1 << 1), 00499 OPT_UNAVAIL_GREETING = (1 << 2), 00500 OPT_RECORDGAIN = (1 << 3), 00501 OPT_PREPEND_MAILBOX = (1 << 4), 00502 OPT_AUTOPLAY = (1 << 6), 00503 OPT_DTMFEXIT = (1 << 7), 00504 OPT_MESSAGE_Urgent = (1 << 8), 00505 OPT_MESSAGE_PRIORITY = (1 << 9) 00506 };
enum vm_passwordlocation |
OPT_PWLOC_VOICEMAILCONF | |
OPT_PWLOC_SPOOLDIR | |
OPT_PWLOC_USERSCONF | |
OPT_PWLOC_VOICEMAILCONF | |
OPT_PWLOC_SPOOLDIR | |
OPT_PWLOC_USERSCONF | |
OPT_PWLOC_VOICEMAILCONF | |
OPT_PWLOC_SPOOLDIR | |
OPT_PWLOC_USERSCONF |
Definition at line 516 of file app_voicemail.c.
00516 { 00517 OPT_PWLOC_VOICEMAILCONF = 0, 00518 OPT_PWLOC_SPOOLDIR = 1, 00519 OPT_PWLOC_USERSCONF = 2, 00520 };
static int __has_voicemail | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder, | |||
int | shortcircuit | |||
) | [static] |
Definition at line 5422 of file app_voicemail.c.
References ast_strlen_zero(), and VM_SPOOL_DIR.
Referenced by has_voicemail(), inboxcount2(), and messagecount().
05423 { 05424 DIR *dir; 05425 struct dirent *de; 05426 char fn[256]; 05427 int ret = 0; 05428 05429 /* If no mailbox, return immediately */ 05430 if (ast_strlen_zero(mailbox)) 05431 return 0; 05432 05433 if (ast_strlen_zero(folder)) 05434 folder = "INBOX"; 05435 if (ast_strlen_zero(context)) 05436 context = "default"; 05437 05438 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05439 05440 if (!(dir = opendir(fn))) 05441 return 0; 05442 05443 while ((de = readdir(dir))) { 05444 if (!strncasecmp(de->d_name, "msg", 3)) { 05445 if (shortcircuit) { 05446 ret = 1; 05447 break; 05448 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05449 ret++; 05450 } 05451 } 05452 } 05453 05454 closedir(dir); 05455 05456 return ret; 05457 }
static int acf_mailbox_exists | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | args, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10999 of file app_voicemail.c.
References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_strlen_zero(), find_user(), LOG_ERROR, and mbox().
11000 { 11001 struct ast_vm_user svm; 11002 AST_DECLARE_APP_ARGS(arg, 11003 AST_APP_ARG(mbox); 11004 AST_APP_ARG(context); 11005 ); 11006 11007 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11008 11009 if (ast_strlen_zero(arg.mbox)) { 11010 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11011 return -1; 11012 } 11013 11014 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11015 return 0; 11016 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11833 of file app_voicemail.c.
References adsifdn, adsisec, adsiver, append_mailbox(), apply_options_full(), ast_category_browse(), ast_config_option(), ast_copy_string(), ast_debug, ast_dsp_get_threshold_from_settings(), ast_false(), ast_format_str_reduce(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_LOG_DEBUG, AST_LOG_ERROR, AST_LOG_WARNING, ast_malloc, AST_PTHREADT_NULL, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, ast_vm_user::context, DEFAULT_LISTEN_CONTROL_FORWARD_KEY, DEFAULT_LISTEN_CONTROL_PAUSE_KEY, DEFAULT_LISTEN_CONTROL_RESTART_KEY, DEFAULT_LISTEN_CONTROL_REVERSE_KEY, DEFAULT_LISTEN_CONTROL_STOP_KEY, DEFAULT_POLL_FREQ, dialcontext, emailbody, emaildateformat, emailsubject, exitcontext, ext_pass_check_cmd, ext_pass_cmd, externnotify, find_or_create(), free_vm_users(), free_vm_zones(), fromstring, globalflags, is_valid_dtmf(), ast_variable::lineno, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, locale, LOG_ERROR, ast_vm_user::mailbox, mailcmd, MAX_NUM_CID_CONTEXTS, maxdeletedmsg, maxgreet, maxlogins, MAXMSG, maxmsg, MAXMSGLIMIT, maxsilence, MINPASSWORD, minpassword, ast_variable::name, ast_variable::next, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, pagerbody, pagerdateformat, pagerfromstring, pagersubject, ast_vm_user::password, ast_vm_user::passwordlocation, passwordlocation, poll_freq, poll_mailboxes, poll_thread, populate_defaults(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, read_password_from_file(), saydurationminfo, SENDMAIL, serveremail, silencethreshold, skipms, smdi_iface, start_poll_thread(), stop_poll_thread(), substitute_escapes(), THRESHOLD_SILENCE, userscontext, ast_variable::value, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_FWDURGAUTO, vm_invalid_password, VM_MESSAGEWRAP, vm_mismatch, VM_MOVEHEARD, vm_newpassword, VM_OPERATOR, vm_passchanged, vm_password, VM_PBXSKIP, vm_pls_try_again, vm_prepend_timeout, vm_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SPOOL_DIR, VM_SVMAIL, VM_TEMPGREETWARN, vmfmts, vmmaxsecs, vmminsecs, volgain, and zonetag.
Referenced by load_config().
11834 { 11835 struct ast_vm_user *current; 11836 char *cat; 11837 struct ast_variable *var; 11838 const char *val; 11839 char *q, *stringp, *tmp; 11840 int x; 11841 unsigned int tmpadsi[4]; 11842 char secretfn[PATH_MAX] = ""; 11843 11844 #ifdef IMAP_STORAGE 11845 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11846 #endif 11847 /* set audio control prompts */ 11848 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11849 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11850 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11851 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11852 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11853 11854 /* Free all the users structure */ 11855 free_vm_users(); 11856 11857 /* Free all the zones structure */ 11858 free_vm_zones(); 11859 11860 AST_LIST_LOCK(&users); 11861 11862 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11863 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11864 11865 if (cfg) { 11866 /* General settings */ 11867 11868 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11869 val = "default"; 11870 ast_copy_string(userscontext, val, sizeof(userscontext)); 11871 /* Attach voice message to mail message ? */ 11872 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11873 val = "yes"; 11874 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11875 11876 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11877 val = "no"; 11878 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11879 11880 volgain = 0.0; 11881 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11882 sscanf(val, "%30lf", &volgain); 11883 11884 #ifdef ODBC_STORAGE 11885 strcpy(odbc_database, "asterisk"); 11886 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11887 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11888 } 11889 strcpy(odbc_table, "voicemessages"); 11890 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11891 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11892 } 11893 #endif 11894 /* Mail command */ 11895 strcpy(mailcmd, SENDMAIL); 11896 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11897 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11898 11899 maxsilence = 0; 11900 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11901 maxsilence = atoi(val); 11902 if (maxsilence > 0) 11903 maxsilence *= 1000; 11904 } 11905 11906 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11907 maxmsg = MAXMSG; 11908 } else { 11909 maxmsg = atoi(val); 11910 if (maxmsg < 0) { 11911 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11912 maxmsg = MAXMSG; 11913 } else if (maxmsg > MAXMSGLIMIT) { 11914 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11915 maxmsg = MAXMSGLIMIT; 11916 } 11917 } 11918 11919 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11920 maxdeletedmsg = 0; 11921 } else { 11922 if (sscanf(val, "%30d", &x) == 1) 11923 maxdeletedmsg = x; 11924 else if (ast_true(val)) 11925 maxdeletedmsg = MAXMSG; 11926 else 11927 maxdeletedmsg = 0; 11928 11929 if (maxdeletedmsg < 0) { 11930 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11931 maxdeletedmsg = MAXMSG; 11932 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11933 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11934 maxdeletedmsg = MAXMSGLIMIT; 11935 } 11936 } 11937 11938 /* Load date format config for voicemail mail */ 11939 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11940 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11941 } 11942 11943 /* Load date format config for voicemail pager mail */ 11944 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11945 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11946 } 11947 11948 /* External password changing command */ 11949 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11950 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11951 pwdchange = PWDCHANGE_EXTERNAL; 11952 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 11953 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11954 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 11955 } 11956 11957 /* External password validation command */ 11958 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 11959 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 11960 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 11961 } 11962 11963 #ifdef IMAP_STORAGE 11964 /* IMAP server address */ 11965 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 11966 ast_copy_string(imapserver, val, sizeof(imapserver)); 11967 } else { 11968 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 11969 } 11970 /* IMAP server port */ 11971 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 11972 ast_copy_string(imapport, val, sizeof(imapport)); 11973 } else { 11974 ast_copy_string(imapport, "143", sizeof(imapport)); 11975 } 11976 /* IMAP server flags */ 11977 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 11978 ast_copy_string(imapflags, val, sizeof(imapflags)); 11979 } 11980 /* IMAP server master username */ 11981 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 11982 ast_copy_string(authuser, val, sizeof(authuser)); 11983 } 11984 /* IMAP server master password */ 11985 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 11986 ast_copy_string(authpassword, val, sizeof(authpassword)); 11987 } 11988 /* Expunge on exit */ 11989 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 11990 if (ast_false(val)) 11991 expungeonhangup = 0; 11992 else 11993 expungeonhangup = 1; 11994 } else { 11995 expungeonhangup = 1; 11996 } 11997 /* IMAP voicemail folder */ 11998 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 11999 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12000 } else { 12001 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12002 } 12003 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12004 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12005 } 12006 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12007 imapgreetings = ast_true(val); 12008 } else { 12009 imapgreetings = 0; 12010 } 12011 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12012 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12013 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12014 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12015 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12016 } else { 12017 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12018 } 12019 12020 /* There is some very unorthodox casting done here. This is due 12021 * to the way c-client handles the argument passed in. It expects a 12022 * void pointer and casts the pointer directly to a long without 12023 * first dereferencing it. */ 12024 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12025 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12026 } else { 12027 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12028 } 12029 12030 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12031 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12032 } else { 12033 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12034 } 12035 12036 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12037 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12038 } else { 12039 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12040 } 12041 12042 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12043 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12044 } else { 12045 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12046 } 12047 12048 /* Increment configuration version */ 12049 imapversion++; 12050 #endif 12051 /* External voicemail notify application */ 12052 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12053 ast_copy_string(externnotify, val, sizeof(externnotify)); 12054 ast_debug(1, "found externnotify: %s\n", externnotify); 12055 } else { 12056 externnotify[0] = '\0'; 12057 } 12058 12059 /* SMDI voicemail notification */ 12060 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12061 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12062 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12063 smdi_iface = ast_smdi_interface_find(val); 12064 } else { 12065 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12066 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12067 } 12068 if (!smdi_iface) { 12069 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12070 } 12071 } 12072 12073 /* Silence treshold */ 12074 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12075 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12076 silencethreshold = atoi(val); 12077 12078 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12079 val = ASTERISK_USERNAME; 12080 ast_copy_string(serveremail, val, sizeof(serveremail)); 12081 12082 vmmaxsecs = 0; 12083 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12084 if (sscanf(val, "%30d", &x) == 1) { 12085 vmmaxsecs = x; 12086 } else { 12087 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12088 } 12089 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12090 static int maxmessage_deprecate = 0; 12091 if (maxmessage_deprecate == 0) { 12092 maxmessage_deprecate = 1; 12093 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12094 } 12095 if (sscanf(val, "%30d", &x) == 1) { 12096 vmmaxsecs = x; 12097 } else { 12098 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12099 } 12100 } 12101 12102 vmminsecs = 0; 12103 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12104 if (sscanf(val, "%30d", &x) == 1) { 12105 vmminsecs = x; 12106 if (maxsilence / 1000 >= vmminsecs) { 12107 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12108 } 12109 } else { 12110 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12111 } 12112 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12113 static int maxmessage_deprecate = 0; 12114 if (maxmessage_deprecate == 0) { 12115 maxmessage_deprecate = 1; 12116 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12117 } 12118 if (sscanf(val, "%30d", &x) == 1) { 12119 vmminsecs = x; 12120 if (maxsilence / 1000 >= vmminsecs) { 12121 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12122 } 12123 } else { 12124 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12125 } 12126 } 12127 12128 val = ast_variable_retrieve(cfg, "general", "format"); 12129 if (!val) { 12130 val = "wav"; 12131 } else { 12132 tmp = ast_strdupa(val); 12133 val = ast_format_str_reduce(tmp); 12134 if (!val) { 12135 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12136 val = "wav"; 12137 } 12138 } 12139 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12140 12141 skipms = 3000; 12142 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12143 if (sscanf(val, "%30d", &x) == 1) { 12144 maxgreet = x; 12145 } else { 12146 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12147 } 12148 } 12149 12150 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12151 if (sscanf(val, "%30d", &x) == 1) { 12152 skipms = x; 12153 } else { 12154 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12155 } 12156 } 12157 12158 maxlogins = 3; 12159 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12160 if (sscanf(val, "%30d", &x) == 1) { 12161 maxlogins = x; 12162 } else { 12163 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12164 } 12165 } 12166 12167 minpassword = MINPASSWORD; 12168 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12169 if (sscanf(val, "%30d", &x) == 1) { 12170 minpassword = x; 12171 } else { 12172 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12173 } 12174 } 12175 12176 /* Force new user to record name ? */ 12177 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12178 val = "no"; 12179 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12180 12181 /* Force new user to record greetings ? */ 12182 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12183 val = "no"; 12184 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12185 12186 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12187 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12188 stringp = ast_strdupa(val); 12189 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12190 if (!ast_strlen_zero(stringp)) { 12191 q = strsep(&stringp, ","); 12192 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12193 q++; 12194 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12195 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12196 } else { 12197 cidinternalcontexts[x][0] = '\0'; 12198 } 12199 } 12200 } 12201 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12202 ast_debug(1, "VM Review Option disabled globally\n"); 12203 val = "no"; 12204 } 12205 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12206 12207 /* Temporary greeting reminder */ 12208 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12209 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12210 val = "no"; 12211 } else { 12212 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12213 } 12214 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12215 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12216 ast_debug(1, "VM next message wrap disabled globally\n"); 12217 val = "no"; 12218 } 12219 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12220 12221 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12222 ast_debug(1, "VM Operator break disabled globally\n"); 12223 val = "no"; 12224 } 12225 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12226 12227 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12228 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12229 val = "no"; 12230 } 12231 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12232 12233 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12234 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12235 val = "no"; 12236 } 12237 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12238 12239 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12240 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12241 val = "yes"; 12242 } 12243 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12244 12245 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12246 ast_debug(1, "Move Heard enabled globally\n"); 12247 val = "yes"; 12248 } 12249 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12250 12251 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12252 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12253 val = "no"; 12254 } 12255 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12256 12257 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12258 ast_debug(1, "Duration info before msg enabled globally\n"); 12259 val = "yes"; 12260 } 12261 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12262 12263 saydurationminfo = 2; 12264 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12265 if (sscanf(val, "%30d", &x) == 1) { 12266 saydurationminfo = x; 12267 } else { 12268 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12269 } 12270 } 12271 12272 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12273 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12274 val = "no"; 12275 } 12276 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12277 12278 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12279 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12280 ast_debug(1, "found dialout context: %s\n", dialcontext); 12281 } else { 12282 dialcontext[0] = '\0'; 12283 } 12284 12285 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12286 ast_copy_string(callcontext, val, sizeof(callcontext)); 12287 ast_debug(1, "found callback context: %s\n", callcontext); 12288 } else { 12289 callcontext[0] = '\0'; 12290 } 12291 12292 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12293 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12294 ast_debug(1, "found operator context: %s\n", exitcontext); 12295 } else { 12296 exitcontext[0] = '\0'; 12297 } 12298 12299 /* load password sounds configuration */ 12300 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12301 ast_copy_string(vm_password, val, sizeof(vm_password)); 12302 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12303 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12304 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12305 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12306 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12307 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12308 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12309 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12310 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12311 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12312 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12313 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12314 } 12315 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12316 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12317 } 12318 /* load configurable audio prompts */ 12319 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12320 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12321 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12322 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12323 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12324 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12325 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12326 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12327 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12328 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12329 12330 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12331 val = "no"; 12332 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12333 12334 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12335 val = "voicemail.conf"; 12336 } 12337 if (!(strcmp(val, "spooldir"))) { 12338 passwordlocation = OPT_PWLOC_SPOOLDIR; 12339 } else { 12340 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12341 } 12342 12343 poll_freq = DEFAULT_POLL_FREQ; 12344 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12345 if (sscanf(val, "%30u", &poll_freq) != 1) { 12346 poll_freq = DEFAULT_POLL_FREQ; 12347 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12348 } 12349 } 12350 12351 poll_mailboxes = 0; 12352 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12353 poll_mailboxes = ast_true(val); 12354 12355 memset(fromstring, 0, sizeof(fromstring)); 12356 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12357 strcpy(charset, "ISO-8859-1"); 12358 if (emailbody) { 12359 ast_free(emailbody); 12360 emailbody = NULL; 12361 } 12362 if (emailsubject) { 12363 ast_free(emailsubject); 12364 emailsubject = NULL; 12365 } 12366 if (pagerbody) { 12367 ast_free(pagerbody); 12368 pagerbody = NULL; 12369 } 12370 if (pagersubject) { 12371 ast_free(pagersubject); 12372 pagersubject = NULL; 12373 } 12374 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12375 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12376 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12377 ast_copy_string(fromstring, val, sizeof(fromstring)); 12378 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12379 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12380 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12381 ast_copy_string(charset, val, sizeof(charset)); 12382 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12383 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12384 for (x = 0; x < 4; x++) { 12385 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12386 } 12387 } 12388 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12389 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12390 for (x = 0; x < 4; x++) { 12391 memcpy(&adsisec[x], &tmpadsi[x], 1); 12392 } 12393 } 12394 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12395 if (atoi(val)) { 12396 adsiver = atoi(val); 12397 } 12398 } 12399 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12400 ast_copy_string(zonetag, val, sizeof(zonetag)); 12401 } 12402 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12403 ast_copy_string(locale, val, sizeof(locale)); 12404 } 12405 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12406 emailsubject = ast_strdup(substitute_escapes(val)); 12407 } 12408 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12409 emailbody = ast_strdup(substitute_escapes(val)); 12410 } 12411 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12412 pagersubject = ast_strdup(substitute_escapes(val)); 12413 } 12414 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12415 pagerbody = ast_strdup(substitute_escapes(val)); 12416 } 12417 12418 /* load mailboxes from users.conf */ 12419 if (ucfg) { 12420 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12421 if (!strcasecmp(cat, "general")) { 12422 continue; 12423 } 12424 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12425 continue; 12426 if ((current = find_or_create(userscontext, cat))) { 12427 populate_defaults(current); 12428 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12429 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12430 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12431 current->passwordlocation = OPT_PWLOC_USERSCONF; 12432 } 12433 12434 switch (current->passwordlocation) { 12435 case OPT_PWLOC_SPOOLDIR: 12436 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12437 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12438 } 12439 } 12440 } 12441 } 12442 12443 /* load mailboxes from voicemail.conf */ 12444 cat = ast_category_browse(cfg, NULL); 12445 while (cat) { 12446 if (strcasecmp(cat, "general")) { 12447 var = ast_variable_browse(cfg, cat); 12448 if (strcasecmp(cat, "zonemessages")) { 12449 /* Process mailboxes in this context */ 12450 while (var) { 12451 append_mailbox(cat, var->name, var->value); 12452 var = var->next; 12453 } 12454 } else { 12455 /* Timezones in this context */ 12456 while (var) { 12457 struct vm_zone *z; 12458 if ((z = ast_malloc(sizeof(*z)))) { 12459 char *msg_format, *tzone; 12460 msg_format = ast_strdupa(var->value); 12461 tzone = strsep(&msg_format, "|,"); 12462 if (msg_format) { 12463 ast_copy_string(z->name, var->name, sizeof(z->name)); 12464 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12465 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12466 AST_LIST_LOCK(&zones); 12467 AST_LIST_INSERT_HEAD(&zones, z, list); 12468 AST_LIST_UNLOCK(&zones); 12469 } else { 12470 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12471 ast_free(z); 12472 } 12473 } else { 12474 AST_LIST_UNLOCK(&users); 12475 return -1; 12476 } 12477 var = var->next; 12478 } 12479 } 12480 } 12481 cat = ast_category_browse(cfg, cat); 12482 } 12483 12484 AST_LIST_UNLOCK(&users); 12485 12486 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12487 start_poll_thread(); 12488 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12489 stop_poll_thread();; 12490 12491 return 0; 12492 } else { 12493 AST_LIST_UNLOCK(&users); 12494 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12495 return 0; 12496 } 12497 }
static int add_email_attachment | ( | FILE * | p, | |
struct ast_vm_user * | vmu, | |||
char * | format, | |||
char * | attach, | |||
char * | greeting_attachment, | |||
char * | mailbox, | |||
char * | bound, | |||
char * | filename, | |||
int | last, | |||
int | msgnum | |||
) | [static] |
Definition at line 4836 of file app_voicemail.c.
References ast_debug, ast_log(), ast_safe_system(), base_encode(), ast_vm_user::context, create_dirpath(), ENDL, LOG_WARNING, ast_vm_user::mailbox, my_umask, VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.
Referenced by make_email_file().
04837 { 04838 char tmpdir[256], newtmp[256]; 04839 char fname[256]; 04840 char tmpcmd[256]; 04841 int tmpfd = -1; 04842 int soxstatus = 0; 04843 04844 /* Eww. We want formats to tell us their own MIME type */ 04845 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04846 04847 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04848 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04849 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04850 tmpfd = mkstemp(newtmp); 04851 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04852 ast_debug(3, "newtmp: %s\n", newtmp); 04853 if (tmpfd > -1) { 04854 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04855 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04856 attach = newtmp; 04857 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04858 } else { 04859 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04860 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04861 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04862 } 04863 } 04864 } 04865 fprintf(p, "--%s" ENDL, bound); 04866 if (msgnum > -1) 04867 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04868 else 04869 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04870 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04871 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04872 if (msgnum > -1) 04873 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04874 else 04875 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04876 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04877 base_encode(fname, p); 04878 if (last) 04879 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04880 if (tmpfd > -1) { 04881 if (soxstatus == 0) { 04882 unlink(fname); 04883 } 04884 close(tmpfd); 04885 unlink(newtmp); 04886 } 04887 return 0; 04888 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6445 of file app_voicemail.c.
References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available(), ast_adsi_load_session(), ast_log(), and AST_LOG_WARNING.
Referenced by vm_authenticate(), and vm_execmain().
06446 { 06447 int x; 06448 if (!ast_adsi_available(chan)) 06449 return; 06450 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06451 if (x < 0) 06452 return; 06453 if (!x) { 06454 if (adsi_load_vmail(chan, useadsi)) { 06455 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06456 return; 06457 } 06458 } else 06459 *useadsi = 1; 06460 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6640 of file app_voicemail.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_set_keys(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_mutex_lock, ast_mutex_unlock, vm_state::curmsg, vm_state::deleted, and vm_state::lastmsg.
Referenced by vm_execmain().
06641 { 06642 int bytes = 0; 06643 unsigned char buf[256]; 06644 unsigned char keys[8]; 06645 06646 int x; 06647 06648 if (!ast_adsi_available(chan)) 06649 return; 06650 06651 /* New meaning for keys */ 06652 for (x = 0; x < 5; x++) 06653 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06654 06655 keys[6] = 0x0; 06656 keys[7] = 0x0; 06657 06658 if (!vms->curmsg) { 06659 /* No prev key, provide "Folder" instead */ 06660 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06661 } 06662 if (vms->curmsg >= vms->lastmsg) { 06663 /* If last message ... */ 06664 if (vms->curmsg) { 06665 /* but not only message, provide "Folder" instead */ 06666 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06667 } else { 06668 /* Otherwise if only message, leave blank */ 06669 keys[3] = 1; 06670 } 06671 } 06672 06673 /* If deleted, show "undeleted" */ 06674 #ifdef IMAP_STORAGE 06675 ast_mutex_lock(&vms->lock); 06676 #endif 06677 if (vms->deleted[vms->curmsg]) { 06678 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06679 } 06680 #ifdef IMAP_STORAGE 06681 ast_mutex_unlock(&vms->lock); 06682 #endif 06683 06684 /* Except "Exit" */ 06685 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06686 bytes += ast_adsi_set_keys(buf + bytes, keys); 06687 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06688 06689 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06690 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6510 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(), and ast_adsi_voice_mode().
Referenced by vm_execmain().
06511 { 06512 unsigned char buf[256]; 06513 int bytes = 0; 06514 unsigned char keys[8]; 06515 int x, y; 06516 06517 if (!ast_adsi_available(chan)) 06518 return; 06519 06520 for (x = 0; x < 5; x++) { 06521 y = ADSI_KEY_APPS + 12 + start + x; 06522 if (y > ADSI_KEY_APPS + 12 + 4) 06523 y = 0; 06524 keys[x] = ADSI_KEY_SKT | y; 06525 } 06526 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06527 keys[6] = 0; 06528 keys[7] = 0; 06529 06530 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06531 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06532 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06533 bytes += ast_adsi_set_keys(buf + bytes, keys); 06534 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06535 06536 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06537 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6795 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().
06796 { 06797 unsigned char buf[256]; 06798 int bytes = 0; 06799 06800 if (!ast_adsi_available(chan)) 06801 return; 06802 bytes += adsi_logo(buf + bytes); 06803 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06804 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06805 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06806 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06807 06808 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06809 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6316 of file app_voicemail.c.
References addesc, ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, adsifdn, adsisec, adsiver, 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_debug, and mbox().
Referenced by adsi_begin().
06317 { 06318 unsigned char buf[256]; 06319 int bytes = 0; 06320 int x; 06321 char num[5]; 06322 06323 *useadsi = 0; 06324 bytes += ast_adsi_data_mode(buf + bytes); 06325 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06326 06327 bytes = 0; 06328 bytes += adsi_logo(buf); 06329 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06330 #ifdef DISPLAY 06331 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06332 #endif 06333 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06334 bytes += ast_adsi_data_mode(buf + bytes); 06335 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06336 06337 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06338 bytes = 0; 06339 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06340 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06341 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06342 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06343 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06344 return 0; 06345 } 06346 06347 #ifdef DISPLAY 06348 /* Add a dot */ 06349 bytes = 0; 06350 bytes += ast_adsi_logo(buf); 06351 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06352 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06353 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06354 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06355 #endif 06356 bytes = 0; 06357 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06358 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06359 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06360 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06361 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06362 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06363 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06364 06365 #ifdef DISPLAY 06366 /* Add another dot */ 06367 bytes = 0; 06368 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06369 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06370 06371 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06372 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06373 #endif 06374 06375 bytes = 0; 06376 /* These buttons we load but don't use yet */ 06377 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06378 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06379 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06380 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06381 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06382 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06383 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06384 06385 #ifdef DISPLAY 06386 /* Add another dot */ 06387 bytes = 0; 06388 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06389 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06390 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06391 #endif 06392 06393 bytes = 0; 06394 for (x = 0; x < 5; x++) { 06395 snprintf(num, sizeof(num), "%d", x); 06396 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06397 } 06398 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06399 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06400 06401 #ifdef DISPLAY 06402 /* Add another dot */ 06403 bytes = 0; 06404 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06405 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06406 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06407 #endif 06408 06409 if (ast_adsi_end_download(chan)) { 06410 bytes = 0; 06411 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06412 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06413 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06414 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06415 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06416 return 0; 06417 } 06418 bytes = 0; 06419 bytes += ast_adsi_download_disconnect(buf + bytes); 06420 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06421 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06422 06423 ast_debug(1, "Done downloading scripts...\n"); 06424 06425 #ifdef DISPLAY 06426 /* Add last dot */ 06427 bytes = 0; 06428 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06429 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06430 #endif 06431 ast_debug(1, "Restarting session...\n"); 06432 06433 bytes = 0; 06434 /* Load the session now */ 06435 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06436 *useadsi = 1; 06437 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06438 } else 06439 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06440 06441 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06442 return 0; 06443 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6462 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(), and ast_adsi_voice_mode().
Referenced by vm_authenticate().
06463 { 06464 unsigned char buf[256]; 06465 int bytes = 0; 06466 unsigned char keys[8]; 06467 int x; 06468 if (!ast_adsi_available(chan)) 06469 return; 06470 06471 for (x = 0; x < 8; x++) 06472 keys[x] = 0; 06473 /* Set one key for next */ 06474 keys[3] = ADSI_KEY_APPS + 3; 06475 06476 bytes += adsi_logo(buf + bytes); 06477 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06478 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06479 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06480 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06481 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06482 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06483 bytes += ast_adsi_set_keys(buf + bytes, keys); 06484 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06485 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06486 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6308 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().
06309 { 06310 int bytes = 0; 06311 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06312 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06313 return bytes; 06314 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6539 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(), ast_callerid_parse(), ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), vm_state::curbox, vm_state::curmsg, vm_state::deleted, vm_state::fn, vm_state::lastmsg, and name.
Referenced by play_message(), and vm_execmain().
06540 { 06541 int bytes = 0; 06542 unsigned char buf[256]; 06543 char buf1[256], buf2[256]; 06544 char fn2[PATH_MAX]; 06545 06546 char cid[256] = ""; 06547 char *val; 06548 char *name, *num; 06549 char datetime[21] = ""; 06550 FILE *f; 06551 06552 unsigned char keys[8]; 06553 06554 int x; 06555 06556 if (!ast_adsi_available(chan)) 06557 return; 06558 06559 /* Retrieve important info */ 06560 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06561 f = fopen(fn2, "r"); 06562 if (f) { 06563 while (!feof(f)) { 06564 if (!fgets((char *) buf, sizeof(buf), f)) { 06565 continue; 06566 } 06567 if (!feof(f)) { 06568 char *stringp = NULL; 06569 stringp = (char *) buf; 06570 strsep(&stringp, "="); 06571 val = strsep(&stringp, "="); 06572 if (!ast_strlen_zero(val)) { 06573 if (!strcmp((char *) buf, "callerid")) 06574 ast_copy_string(cid, val, sizeof(cid)); 06575 if (!strcmp((char *) buf, "origdate")) 06576 ast_copy_string(datetime, val, sizeof(datetime)); 06577 } 06578 } 06579 } 06580 fclose(f); 06581 } 06582 /* New meaning for keys */ 06583 for (x = 0; x < 5; x++) 06584 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06585 keys[6] = 0x0; 06586 keys[7] = 0x0; 06587 06588 if (!vms->curmsg) { 06589 /* No prev key, provide "Folder" instead */ 06590 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06591 } 06592 if (vms->curmsg >= vms->lastmsg) { 06593 /* If last message ... */ 06594 if (vms->curmsg) { 06595 /* but not only message, provide "Folder" instead */ 06596 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06597 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06598 06599 } else { 06600 /* Otherwise if only message, leave blank */ 06601 keys[3] = 1; 06602 } 06603 } 06604 06605 if (!ast_strlen_zero(cid)) { 06606 ast_callerid_parse(cid, &name, &num); 06607 if (!name) 06608 name = num; 06609 } else 06610 name = "Unknown Caller"; 06611 06612 /* If deleted, show "undeleted" */ 06613 #ifdef IMAP_STORAGE 06614 ast_mutex_lock(&vms->lock); 06615 #endif 06616 if (vms->deleted[vms->curmsg]) { 06617 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06618 } 06619 #ifdef IMAP_STORAGE 06620 ast_mutex_unlock(&vms->lock); 06621 #endif 06622 06623 /* Except "Exit" */ 06624 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06625 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06626 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06627 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06628 06629 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06630 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06631 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06632 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06633 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06634 bytes += ast_adsi_set_keys(buf + bytes, keys); 06635 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06636 06637 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06638 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6488 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(), and ast_adsi_voice_mode().
Referenced by vm_authenticate().
06489 { 06490 unsigned char buf[256]; 06491 int bytes = 0; 06492 unsigned char keys[8]; 06493 int x; 06494 if (!ast_adsi_available(chan)) 06495 return; 06496 06497 for (x = 0; x < 8; x++) 06498 keys[x] = 0; 06499 /* Set one key for next */ 06500 keys[3] = ADSI_KEY_APPS + 3; 06501 06502 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06503 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06504 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06505 bytes += ast_adsi_set_keys(buf + bytes, keys); 06506 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06507 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06508 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6692 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::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_execmain().
06693 { 06694 unsigned char buf[256] = ""; 06695 char buf1[256] = "", buf2[256] = ""; 06696 int bytes = 0; 06697 unsigned char keys[8]; 06698 int x; 06699 06700 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06701 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06702 if (!ast_adsi_available(chan)) 06703 return; 06704 if (vms->newmessages) { 06705 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06706 if (vms->oldmessages) { 06707 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06708 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06709 } else { 06710 snprintf(buf2, sizeof(buf2), "%s.", newm); 06711 } 06712 } else if (vms->oldmessages) { 06713 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06714 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06715 } else { 06716 strcpy(buf1, "You have no messages."); 06717 buf2[0] = ' '; 06718 buf2[1] = '\0'; 06719 } 06720 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06721 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06722 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06723 06724 for (x = 0; x < 6; x++) 06725 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06726 keys[6] = 0; 06727 keys[7] = 0; 06728 06729 /* Don't let them listen if there are none */ 06730 if (vms->lastmsg < 0) 06731 keys[0] = 1; 06732 bytes += ast_adsi_set_keys(buf + bytes, keys); 06733 06734 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06735 06736 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06737 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6739 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, and vm_state::lastmsg.
Referenced by vm_execmain().
06740 { 06741 unsigned char buf[256] = ""; 06742 char buf1[256] = "", buf2[256] = ""; 06743 int bytes = 0; 06744 unsigned char keys[8]; 06745 int x; 06746 06747 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06748 06749 if (!ast_adsi_available(chan)) 06750 return; 06751 06752 /* Original command keys */ 06753 for (x = 0; x < 6; x++) 06754 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06755 06756 keys[6] = 0; 06757 keys[7] = 0; 06758 06759 if ((vms->lastmsg + 1) < 1) 06760 keys[0] = 0; 06761 06762 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06763 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06764 06765 if (vms->lastmsg + 1) 06766 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06767 else 06768 strcpy(buf2, "no messages."); 06769 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06770 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06771 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06772 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06773 bytes += ast_adsi_set_keys(buf + bytes, keys); 06774 06775 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06776 06777 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06778 06779 }
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] |
The advanced options within a message.
chan | ||
vmu | ||
vms | ||
msg | ||
option | ||
record_gain | Provides handling for the play message envelope, call the person back, or reply to message. |
Definition at line 13205 of file app_voicemail.c.
References ast_callerid_parse(), ast_config_destroy(), ast_config_load, ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), name, play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, valid_config(), and wait_file().
Referenced by vm_execmain().
13206 { 13207 int res = 0; 13208 char filename[PATH_MAX]; 13209 struct ast_config *msg_cfg = NULL; 13210 const char *origtime, *context; 13211 char *name, *num; 13212 int retries = 0; 13213 char *cid; 13214 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13215 13216 vms->starting = 0; 13217 13218 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13219 13220 /* Retrieve info from VM attribute file */ 13221 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13222 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13223 msg_cfg = ast_config_load(filename, config_flags); 13224 DISPOSE(vms->curdir, vms->curmsg); 13225 if (!valid_config(msg_cfg)) { 13226 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13227 return 0; 13228 } 13229 13230 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13231 ast_config_destroy(msg_cfg); 13232 return 0; 13233 } 13234 13235 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13236 13237 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13238 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13239 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13240 switch (option) { 13241 case 3: /* Play message envelope */ 13242 if (!res) 13243 res = play_message_datetime(chan, vmu, origtime, filename); 13244 if (!res) 13245 res = play_message_callerid(chan, vms, cid, context, 0); 13246 13247 res = 't'; 13248 break; 13249 13250 case 2: /* Call back */ 13251 13252 if (ast_strlen_zero(cid)) 13253 break; 13254 13255 ast_callerid_parse(cid, &name, &num); 13256 while ((res > -1) && (res != 't')) { 13257 switch (res) { 13258 case '1': 13259 if (num) { 13260 /* Dial the CID number */ 13261 res = dialout(chan, vmu, num, vmu->callback); 13262 if (res) { 13263 ast_config_destroy(msg_cfg); 13264 return 9; 13265 } 13266 } else { 13267 res = '2'; 13268 } 13269 break; 13270 13271 case '2': 13272 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13273 if (!ast_strlen_zero(vmu->dialout)) { 13274 res = dialout(chan, vmu, NULL, vmu->dialout); 13275 if (res) { 13276 ast_config_destroy(msg_cfg); 13277 return 9; 13278 } 13279 } else { 13280 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13281 res = ast_play_and_wait(chan, "vm-sorry"); 13282 } 13283 ast_config_destroy(msg_cfg); 13284 return res; 13285 case '*': 13286 res = 't'; 13287 break; 13288 case '3': 13289 case '4': 13290 case '5': 13291 case '6': 13292 case '7': 13293 case '8': 13294 case '9': 13295 case '0': 13296 13297 res = ast_play_and_wait(chan, "vm-sorry"); 13298 retries++; 13299 break; 13300 default: 13301 if (num) { 13302 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13303 res = ast_play_and_wait(chan, "vm-num-i-have"); 13304 if (!res) 13305 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13306 if (!res) 13307 res = ast_play_and_wait(chan, "vm-tocallnum"); 13308 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13309 if (!ast_strlen_zero(vmu->dialout)) { 13310 if (!res) 13311 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13312 } 13313 } else { 13314 res = ast_play_and_wait(chan, "vm-nonumber"); 13315 if (!ast_strlen_zero(vmu->dialout)) { 13316 if (!res) 13317 res = ast_play_and_wait(chan, "vm-toenternumber"); 13318 } 13319 } 13320 if (!res) { 13321 res = ast_play_and_wait(chan, "vm-star-cancel"); 13322 } 13323 if (!res) { 13324 res = ast_waitfordigit(chan, 6000); 13325 } 13326 if (!res) { 13327 retries++; 13328 if (retries > 3) { 13329 res = 't'; 13330 } 13331 } 13332 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13333 break; 13334 13335 } 13336 if (res == 't') 13337 res = 0; 13338 else if (res == '*') 13339 res = -1; 13340 } 13341 break; 13342 13343 case 1: /* Reply */ 13344 /* Send reply directly to sender */ 13345 if (ast_strlen_zero(cid)) 13346 break; 13347 13348 ast_callerid_parse(cid, &name, &num); 13349 if (!num) { 13350 ast_verb(3, "No CID number available, no reply sent\n"); 13351 if (!res) 13352 res = ast_play_and_wait(chan, "vm-nonumber"); 13353 ast_config_destroy(msg_cfg); 13354 return res; 13355 } else { 13356 struct ast_vm_user vmu2; 13357 if (find_user(&vmu2, vmu->context, num)) { 13358 struct leave_vm_options leave_options; 13359 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13360 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13361 13362 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13363 13364 memset(&leave_options, 0, sizeof(leave_options)); 13365 leave_options.record_gain = record_gain; 13366 res = leave_voicemail(chan, mailbox, &leave_options); 13367 if (!res) 13368 res = 't'; 13369 ast_config_destroy(msg_cfg); 13370 return res; 13371 } else { 13372 /* Sender has no mailbox, can't reply */ 13373 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13374 ast_play_and_wait(chan, "vm-nobox"); 13375 res = 't'; 13376 ast_config_destroy(msg_cfg); 13377 return res; 13378 } 13379 } 13380 res = 0; 13381 13382 break; 13383 } 13384 13385 ast_config_destroy(msg_cfg); 13386 13387 #ifndef IMAP_STORAGE 13388 if (!res) { 13389 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13390 vms->heard[msg] = 1; 13391 res = wait_file(chan, vms, vms->fn); 13392 } 13393 #endif 13394 return res; 13395 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10726 of file app_voicemail.c.
References apply_options(), ast_alloca, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, inboxcount2(), LOG_WARNING, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, ast_vm_user::pager, ast_vm_user::password, ast_vm_user::passwordlocation, populate_defaults(), queue_mwi_event(), read_password_from_file(), and VM_SPOOL_DIR.
Referenced by actual_load_config().
10727 { 10728 /* Assumes lock is already held */ 10729 char *tmp; 10730 char *stringp; 10731 char *s; 10732 struct ast_vm_user *vmu; 10733 char *mailbox_full; 10734 int new = 0, old = 0, urgent = 0; 10735 char secretfn[PATH_MAX] = ""; 10736 10737 tmp = ast_strdupa(data); 10738 10739 if (!(vmu = find_or_create(context, box))) 10740 return -1; 10741 10742 populate_defaults(vmu); 10743 10744 stringp = tmp; 10745 if ((s = strsep(&stringp, ","))) { 10746 if (!ast_strlen_zero(s) && s[0] == '*') { 10747 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10748 "\n\tmust be reset in voicemail.conf.\n", box); 10749 } 10750 /* assign password regardless of validity to prevent NULL password from being assigned */ 10751 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10752 } 10753 if (stringp && (s = strsep(&stringp, ","))) { 10754 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10755 } 10756 if (stringp && (s = strsep(&stringp, ","))) { 10757 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10758 } 10759 if (stringp && (s = strsep(&stringp, ","))) { 10760 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10761 } 10762 if (stringp && (s = strsep(&stringp, ","))) { 10763 apply_options(vmu, s); 10764 } 10765 10766 switch (vmu->passwordlocation) { 10767 case OPT_PWLOC_SPOOLDIR: 10768 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10769 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10770 } 10771 10772 mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1); 10773 strcpy(mailbox_full, box); 10774 strcat(mailbox_full, "@"); 10775 strcat(mailbox_full, context); 10776 10777 inboxcount2(mailbox_full, &urgent, &new, &old); 10778 queue_mwi_event(mailbox_full, urgent, new, old); 10779 10780 return 0; 10781 }
static void apply_option | ( | struct ast_vm_user * | vmu, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Sets a a specific property value.
vmu | The voicemail user object to work with. | |
var | The name of the property to be set. | |
value | The value to be set to the property. |
The property name must be one of the understood properties. See the source for details.
Definition at line 1056 of file app_voicemail.c.
References apply_options(), ast_copy_string(), ast_log(), AST_LOG_WARNING, ast_set2_flag, ast_strdup, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, ast_vm_user::language, ast_vm_user::locale, LOG_WARNING, ast_vm_user::maxdeletedmsg, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::maxsecs, ast_vm_user::minsecs, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, ast_vm_user::serveremail, substitute_escapes(), VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, vmmaxsecs, vmminsecs, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by apply_options(), and apply_options_full().
01057 { 01058 int x; 01059 if (!strcasecmp(var, "attach")) { 01060 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01061 } else if (!strcasecmp(var, "attachfmt")) { 01062 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01063 } else if (!strcasecmp(var, "serveremail")) { 01064 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01065 } else if (!strcasecmp(var, "emailbody")) { 01066 vmu->emailbody = ast_strdup(substitute_escapes(value)); 01067 } else if (!strcasecmp(var, "emailsubject")) { 01068 vmu->emailsubject = ast_strdup(substitute_escapes(value)); 01069 } else if (!strcasecmp(var, "language")) { 01070 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01071 } else if (!strcasecmp(var, "tz")) { 01072 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01073 } else if (!strcasecmp(var, "locale")) { 01074 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01075 #ifdef IMAP_STORAGE 01076 } else if (!strcasecmp(var, "imapuser")) { 01077 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01078 vmu->imapversion = imapversion; 01079 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01080 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01081 vmu->imapversion = imapversion; 01082 } else if (!strcasecmp(var, "imapfolder")) { 01083 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01084 } else if (!strcasecmp(var, "imapvmshareid")) { 01085 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01086 vmu->imapversion = imapversion; 01087 #endif 01088 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01089 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01090 } else if (!strcasecmp(var, "saycid")){ 01091 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01092 } else if (!strcasecmp(var, "sendvoicemail")){ 01093 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01094 } else if (!strcasecmp(var, "review")){ 01095 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01096 } else if (!strcasecmp(var, "tempgreetwarn")){ 01097 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01098 } else if (!strcasecmp(var, "messagewrap")){ 01099 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01100 } else if (!strcasecmp(var, "operator")) { 01101 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01102 } else if (!strcasecmp(var, "envelope")){ 01103 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01104 } else if (!strcasecmp(var, "moveheard")){ 01105 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01106 } else if (!strcasecmp(var, "sayduration")){ 01107 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01108 } else if (!strcasecmp(var, "saydurationm")){ 01109 if (sscanf(value, "%30d", &x) == 1) { 01110 vmu->saydurationm = x; 01111 } else { 01112 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01113 } 01114 } else if (!strcasecmp(var, "forcename")){ 01115 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01116 } else if (!strcasecmp(var, "forcegreetings")){ 01117 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01118 } else if (!strcasecmp(var, "callback")) { 01119 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01120 } else if (!strcasecmp(var, "dialout")) { 01121 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01122 } else if (!strcasecmp(var, "exitcontext")) { 01123 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01124 } else if (!strcasecmp(var, "minsecs")) { 01125 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01126 vmu->minsecs = x; 01127 } else { 01128 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01129 vmu->minsecs = vmminsecs; 01130 } 01131 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01132 vmu->maxsecs = atoi(value); 01133 if (vmu->maxsecs <= 0) { 01134 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01135 vmu->maxsecs = vmmaxsecs; 01136 } else { 01137 vmu->maxsecs = atoi(value); 01138 } 01139 if (!strcasecmp(var, "maxmessage")) 01140 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01141 } else if (!strcasecmp(var, "maxmsg")) { 01142 vmu->maxmsg = atoi(value); 01143 /* Accept maxmsg=0 (Greetings only voicemail) */ 01144 if (vmu->maxmsg < 0) { 01145 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01146 vmu->maxmsg = MAXMSG; 01147 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01148 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01149 vmu->maxmsg = MAXMSGLIMIT; 01150 } 01151 } else if (!strcasecmp(var, "nextaftercmd")) { 01152 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01153 } else if (!strcasecmp(var, "backupdeleted")) { 01154 if (sscanf(value, "%30d", &x) == 1) 01155 vmu->maxdeletedmsg = x; 01156 else if (ast_true(value)) 01157 vmu->maxdeletedmsg = MAXMSG; 01158 else 01159 vmu->maxdeletedmsg = 0; 01160 01161 if (vmu->maxdeletedmsg < 0) { 01162 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01163 vmu->maxdeletedmsg = MAXMSG; 01164 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01165 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01166 vmu->maxdeletedmsg = MAXMSGLIMIT; 01167 } 01168 } else if (!strcasecmp(var, "volgain")) { 01169 sscanf(value, "%30lf", &vmu->volgain); 01170 } else if (!strcasecmp(var, "passwordlocation")) { 01171 if (!strcasecmp(value, "spooldir")) { 01172 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01173 } else { 01174 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01175 } 01176 } else if (!strcasecmp(var, "options")) { 01177 apply_options(vmu, value); 01178 } 01179 }
static void apply_options | ( | struct ast_vm_user * | vmu, | |
const char * | options | |||
) | [static] |
Destructively Parse options and apply.
Definition at line 1297 of file app_voicemail.c.
References apply_option(), ast_strdupa, value, and var.
Referenced by append_mailbox(), apply_option(), and AST_TEST_DEFINE().
01298 { 01299 char *stringp; 01300 char *s; 01301 char *var, *value; 01302 stringp = ast_strdupa(options); 01303 while ((s = strsep(&stringp, "|"))) { 01304 value = s; 01305 if ((var = strsep(&value, "=")) && value) { 01306 apply_option(vmu, var, value); 01307 } 01308 } 01309 }
static void apply_options_full | ( | struct ast_vm_user * | retval, | |
struct ast_variable * | var | |||
) | [static] |
Loads the options specific to a voicemail user.
This is called when a vm_user structure is being set up, such as from load_options.
Definition at line 1316 of file app_voicemail.c.
References apply_option(), ast_copy_string(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::fullname, LOG_WARNING, ast_vm_user::mailbox, ast_variable::name, ast_variable::next, ast_vm_user::pager, ast_vm_user::password, substitute_escapes(), ast_vm_user::uniqueid, and ast_variable::value.
Referenced by actual_load_config(), and find_user_realtime().
01317 { 01318 for (; var; var = var->next) { 01319 if (!strcasecmp(var->name, "vmsecret")) { 01320 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01321 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01322 if (ast_strlen_zero(retval->password)) { 01323 if (!ast_strlen_zero(var->value) && var->value[0] == '*') { 01324 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 01325 "\n\tmust be reset in voicemail.conf.\n", retval->mailbox); 01326 } else { 01327 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01328 } 01329 } 01330 } else if (!strcasecmp(var->name, "uniqueid")) { 01331 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01332 } else if (!strcasecmp(var->name, "pager")) { 01333 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01334 } else if (!strcasecmp(var->name, "email")) { 01335 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01336 } else if (!strcasecmp(var->name, "fullname")) { 01337 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01338 } else if (!strcasecmp(var->name, "context")) { 01339 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01340 } else if (!strcasecmp(var->name, "emailsubject")) { 01341 ast_free(retval->emailsubject); 01342 retval->emailsubject = ast_strdup(substitute_escapes(var->value)); 01343 } else if (!strcasecmp(var->name, "emailbody")) { 01344 ast_free(retval->emailbody); 01345 retval->emailbody = ast_strdup(substitute_escapes(var->value)); 01346 #ifdef IMAP_STORAGE 01347 } else if (!strcasecmp(var->name, "imapuser")) { 01348 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01349 retval->imapversion = imapversion; 01350 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01351 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01352 retval->imapversion = imapversion; 01353 } else if (!strcasecmp(var->name, "imapfolder")) { 01354 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01355 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01356 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01357 retval->imapversion = imapversion; 01358 #endif 01359 } else 01360 apply_option(retval, var->name, var->value); 01361 } 01362 }
AST_APP_OPTIONS | ( | vm_app_options | ) |
AST_DATA_STRUCTURE | ( | vm_zone | , | |
DATA_EXPORT_VM_ZONES | ||||
) |
AST_DATA_STRUCTURE | ( | ast_vm_user | , | |
DATA_EXPORT_VM_USERS | ||||
) |
static AST_LIST_HEAD_STATIC | ( | zones | , | |
vm_zone | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | users | , | |
ast_vm_user | ||||
) | [static] |
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
tdesc | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload , |
|||
. | nonoptreq = "res_adsi,res_smdi" | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | poll_lock | ) |
static AST_RWLIST_HEAD_STATIC | ( | mwi_subs | , | |
mwi_sub | ||||
) | [static] |
static const char* ast_str_encode_mime | ( | struct ast_str ** | end, | |
ssize_t | maxlen, | |||
const char * | start, | |||
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.
end | An expandable buffer for holding the result | |
maxlen | Always zero, but see |
start | A string to be encoded | |
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. |
The | encoded string. |
Definition at line 4511 of file app_voicemail.c.
References ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), and charset.
Referenced by make_email_file(), and sendpage().
04512 { 04513 struct ast_str *tmp = ast_str_alloca(80); 04514 int first_section = 1; 04515 04516 ast_str_reset(*end); 04517 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04518 for (; *start; start++) { 04519 int need_encoding = 0; 04520 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04521 need_encoding = 1; 04522 } 04523 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04524 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04525 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04526 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04527 /* Start new line */ 04528 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04529 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04530 first_section = 0; 04531 } 04532 if (need_encoding && *start == ' ') { 04533 ast_str_append(&tmp, -1, "_"); 04534 } else if (need_encoding) { 04535 ast_str_append(&tmp, -1, "=%hhX", *start); 04536 } else { 04537 ast_str_append(&tmp, -1, "%c", *start); 04538 } 04539 } 04540 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04541 return ast_str_buffer(*end); 04542 }
static const char* ast_str_quote | ( | struct ast_str ** | buf, | |
ssize_t | maxlen, | |||
const char * | from | |||
) | [static] |
Wraps a character sequence in double quotes, escaping occurences of quotes within the string.
from | The string to work with. | |
buf | The buffer into which to write the modified quoted string. | |
maxlen | Always zero, but see |
Definition at line 4439 of file app_voicemail.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
Referenced by make_email_file(), and sendpage().
04440 { 04441 const char *ptr; 04442 04443 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04444 ast_str_set(buf, maxlen, "\""); 04445 for (ptr = from; *ptr; ptr++) { 04446 if (*ptr == '"' || *ptr == '\\') { 04447 ast_str_append(buf, maxlen, "\\%c", *ptr); 04448 } else { 04449 ast_str_append(buf, maxlen, "%c", *ptr); 04450 } 04451 } 04452 ast_str_append(buf, maxlen, "\""); 04453 04454 return ast_str_buffer(*buf); 04455 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10783 of file app_voicemail.c.
References apply_options(), ast_calloc, ast_set_flag, AST_TEST_FAIL, ast_test_flag, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, free_user(), ast_vm_user::maxdeletedmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, OPT_PWLOC_SPOOLDIR, ast_vm_user::passwordlocation, populate_defaults(), ast_vm_user::saydurationm, ast_vm_user::serveremail, TEST_EXECUTE, TEST_INIT, VM_ALLOCED, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.
10784 { 10785 int res = 0; 10786 struct ast_vm_user *vmu; 10787 /* language parameter seems to only be used for display in manager action */ 10788 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10789 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10790 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10791 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10792 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10793 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10794 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10795 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10796 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10797 #ifdef IMAP_STORAGE 10798 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10799 "imapfolder=INBOX|imapvmshareid=6000"; 10800 #endif 10801 10802 switch (cmd) { 10803 case TEST_INIT: 10804 info->name = "vmuser"; 10805 info->category = "/apps/app_voicemail/"; 10806 info->summary = "Vmuser unit test"; 10807 info->description = 10808 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10809 return AST_TEST_NOT_RUN; 10810 case TEST_EXECUTE: 10811 break; 10812 } 10813 10814 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10815 return AST_TEST_NOT_RUN; 10816 } 10817 populate_defaults(vmu); 10818 ast_set_flag(vmu, VM_ALLOCED); 10819 10820 apply_options(vmu, options_string); 10821 10822 if (!ast_test_flag(vmu, VM_ATTACH)) { 10823 ast_test_status_update(test, "Parse failure for attach option\n"); 10824 res = 1; 10825 } 10826 if (strcasecmp(vmu->attachfmt, "wav49")) { 10827 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10828 res = 1; 10829 } 10830 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10831 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10832 res = 1; 10833 } 10834 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10835 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10836 res = 1; 10837 } 10838 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10839 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10840 res = 1; 10841 } 10842 if (strcasecmp(vmu->zonetag, "central")) { 10843 ast_test_status_update(test, "Parse failure for tz option\n"); 10844 res = 1; 10845 } 10846 if (!ast_test_flag(vmu, VM_DELETE)) { 10847 ast_test_status_update(test, "Parse failure for delete option\n"); 10848 res = 1; 10849 } 10850 if (!ast_test_flag(vmu, VM_SAYCID)) { 10851 ast_test_status_update(test, "Parse failure for saycid option\n"); 10852 res = 1; 10853 } 10854 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10855 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10856 res = 1; 10857 } 10858 if (!ast_test_flag(vmu, VM_REVIEW)) { 10859 ast_test_status_update(test, "Parse failure for review option\n"); 10860 res = 1; 10861 } 10862 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10863 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10864 res = 1; 10865 } 10866 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10867 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10868 res = 1; 10869 } 10870 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10871 ast_test_status_update(test, "Parse failure for operator option\n"); 10872 res = 1; 10873 } 10874 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10875 ast_test_status_update(test, "Parse failure for envelope option\n"); 10876 res = 1; 10877 } 10878 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10879 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10880 res = 1; 10881 } 10882 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10883 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10884 res = 1; 10885 } 10886 if (vmu->saydurationm != 5) { 10887 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10888 res = 1; 10889 } 10890 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10891 ast_test_status_update(test, "Parse failure for forcename option\n"); 10892 res = 1; 10893 } 10894 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10895 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10896 res = 1; 10897 } 10898 if (strcasecmp(vmu->callback, "somecontext")) { 10899 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10900 res = 1; 10901 } 10902 if (strcasecmp(vmu->dialout, "somecontext2")) { 10903 ast_test_status_update(test, "Parse failure for dialout option\n"); 10904 res = 1; 10905 } 10906 if (strcasecmp(vmu->exit, "somecontext3")) { 10907 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10908 res = 1; 10909 } 10910 if (vmu->minsecs != 10) { 10911 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10912 res = 1; 10913 } 10914 if (vmu->maxsecs != 100) { 10915 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10916 res = 1; 10917 } 10918 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10919 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10920 res = 1; 10921 } 10922 if (vmu->maxdeletedmsg != 50) { 10923 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10924 res = 1; 10925 } 10926 if (vmu->volgain != 1.3) { 10927 ast_test_status_update(test, "Parse failure for volgain option\n"); 10928 res = 1; 10929 } 10930 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10931 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10932 res = 1; 10933 } 10934 #ifdef IMAP_STORAGE 10935 apply_options(vmu, option_string2); 10936 10937 if (strcasecmp(vmu->imapuser, "imapuser")) { 10938 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10939 res = 1; 10940 } 10941 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10942 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10943 res = 1; 10944 } 10945 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10946 ast_test_status_update(test, "Parse failure for imapfolder option\n"); 10947 res = 1; 10948 } 10949 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10950 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10951 res = 1; 10952 } 10953 #endif 10954 10955 free_user(vmu); 10956 return res ? AST_TEST_FAIL : AST_TEST_PASS; 10957 }
static int base_encode | ( | char * | filename, | |
FILE * | so | |||
) | [static] |
Performs a base 64 encode algorithm on the contents of a File.
filename | The path to the file to be encoded. Must be readable, file is opened in read mode. | |
so | A FILE handle to the output file to receive the base 64 encoded contents of the input file, identified by filename. |
TODO: shouldn't this (and the above 3 support functions) be put into some kind of external utility location, such as funcs/func_base64.c ?
Definition at line 4315 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, BASEMAXINLINE, ENDL, errno, inchar(), baseio::iocp, and ochar().
Referenced by add_email_attachment().
04316 { 04317 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04318 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04319 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04320 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04321 int i, hiteof = 0; 04322 FILE *fi; 04323 struct baseio bio; 04324 04325 memset(&bio, 0, sizeof(bio)); 04326 bio.iocp = BASEMAXINLINE; 04327 04328 if (!(fi = fopen(filename, "rb"))) { 04329 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04330 return -1; 04331 } 04332 04333 while (!hiteof){ 04334 unsigned char igroup[3], ogroup[4]; 04335 int c, n; 04336 04337 memset(igroup, 0, sizeof(igroup)); 04338 04339 for (n = 0; n < 3; n++) { 04340 if ((c = inchar(&bio, fi)) == EOF) { 04341 hiteof = 1; 04342 break; 04343 } 04344 04345 igroup[n] = (unsigned char) c; 04346 } 04347 04348 if (n > 0) { 04349 ogroup[0]= dtable[igroup[0] >> 2]; 04350 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04351 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04352 ogroup[3]= dtable[igroup[2] & 0x3F]; 04353 04354 if (n < 3) { 04355 ogroup[3] = '='; 04356 04357 if (n < 2) 04358 ogroup[2] = '='; 04359 } 04360 04361 for (i = 0; i < 4; i++) 04362 ochar(&bio, ogroup[i], so); 04363 } 04364 } 04365 04366 fclose(fi); 04367 04368 if (fputs(ENDL, so) == EOF) { 04369 return 0; 04370 } 04371 04372 return 1; 04373 }
static int change_password_realtime | ( | struct ast_vm_user * | vmu, | |
const char * | password | |||
) | [static] |
Performs a change of the voicemail passowrd in the realtime engine.
vmu | The voicemail user to change the password for. | |
password | The new value to be set to the password for this user. |
This only works if there is a realtime engine configured. This is called from the (top level) vm_change_password.
Definition at line 1275 of file app_voicemail.c.
References ast_copy_string(), ast_realtime_require_field(), ast_test_suite_event_notify, ast_update2_realtime(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, RQ_CHAR, and SENTINEL.
Referenced by vm_change_password().
01276 { 01277 int res = -1; 01278 if (!strcmp(vmu->password, password)) { 01279 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01280 return 0; 01281 } 01282 01283 if (strlen(password) > 10) { 01284 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01285 } 01286 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01287 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime"); 01288 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01289 res = 0; 01290 } 01291 return res; 01292 }
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 4484 of file app_voicemail.c.
Referenced by make_email_file(), and sendpage().
static int check_password | ( | struct ast_vm_user * | vmu, | |
char * | password | |||
) | [static] |
Check that password meets minimum required length.
vmu | The voicemail user to change the password for. | |
password | The password string to check |
Definition at line 1234 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_DEBUG, AST_LOG_NOTICE, AST_LOG_WARNING, ast_strlen_zero(), ast_vm_user::context, ext_pass_check_cmd, ast_vm_user::mailbox, minpassword, ast_vm_user::password, and vm_check_password_shell().
Referenced by vm_newuser(), and vm_options().
01235 { 01236 /* check minimum length */ 01237 if (strlen(password) < minpassword) 01238 return 1; 01239 /* check that password does not contain '*' character */ 01240 if (!ast_strlen_zero(password) && password[0] == '*') 01241 return 1; 01242 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01243 char cmd[255], buf[255]; 01244 01245 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01246 01247 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01248 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01249 ast_debug(5, "Result: %s\n", buf); 01250 if (!strncasecmp(buf, "VALID", 5)) { 01251 ast_debug(3, "Passed password check: '%s'\n", buf); 01252 return 0; 01253 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01254 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01255 return 0; 01256 } else { 01257 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01258 return 1; 01259 } 01260 } 01261 } 01262 return 0; 01263 }
static int close_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 8004 of file app_voicemail.c.
References ast_check_realtime(), ast_debug, ast_free, ast_log(), AST_LOG_NOTICE, AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_test_flag, ast_unlock_path(), ast_vm_user::context, vm_state::curbox, vm_state::curdir, vm_state::curmsg, DELETE, vm_state::deleted, vm_state::dh_arraysize, ERROR_LOCK_PATH, EXISTS, vm_state::fn, vm_state::heard, last_message_index(), vm_state::lastmsg, ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, RENAME, save_to_folder(), vm_lock_path(), and VM_MOVEHEARD.
Referenced by vm_execmain().
08005 { 08006 int x = 0; 08007 int last_msg_idx = 0; 08008 08009 #ifndef IMAP_STORAGE 08010 int res = 0, nummsg; 08011 char fn2[PATH_MAX]; 08012 #endif 08013 08014 if (vms->lastmsg <= -1) { 08015 goto done; 08016 } 08017 08018 vms->curmsg = -1; 08019 #ifndef IMAP_STORAGE 08020 /* Get the deleted messages fixed */ 08021 if (vm_lock_path(vms->curdir)) { 08022 return ERROR_LOCK_PATH; 08023 } 08024 08025 /* update count as message may have arrived while we've got mailbox open */ 08026 last_msg_idx = last_message_index(vmu, vms->curdir); 08027 if (last_msg_idx != vms->lastmsg) { 08028 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 08029 } 08030 08031 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 08032 for (x = 0; x < last_msg_idx + 1; x++) { 08033 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 08034 /* Save this message. It's not in INBOX or hasn't been heard */ 08035 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08036 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 08037 break; 08038 } 08039 vms->curmsg++; 08040 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 08041 if (strcmp(vms->fn, fn2)) { 08042 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 08043 } 08044 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 08045 /* Move to old folder before deleting */ 08046 res = save_to_folder(vmu, vms, x, 1); 08047 if (res == ERROR_LOCK_PATH) { 08048 /* If save failed do not delete the message */ 08049 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 08050 vms->deleted[x] = 0; 08051 vms->heard[x] = 0; 08052 --x; 08053 } 08054 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 08055 /* Move to deleted folder */ 08056 res = save_to_folder(vmu, vms, x, 10); 08057 if (res == ERROR_LOCK_PATH) { 08058 /* If save failed do not delete the message */ 08059 vms->deleted[x] = 0; 08060 vms->heard[x] = 0; 08061 --x; 08062 } 08063 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 08064 /* If realtime storage enabled - we should explicitly delete this message, 08065 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08066 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08067 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08068 DELETE(vms->curdir, x, vms->fn, vmu); 08069 } 08070 } 08071 } 08072 08073 /* Delete ALL remaining messages */ 08074 nummsg = x - 1; 08075 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08076 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08077 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08078 DELETE(vms->curdir, x, vms->fn, vmu); 08079 } 08080 } 08081 ast_unlock_path(vms->curdir); 08082 #else /* defined(IMAP_STORAGE) */ 08083 ast_mutex_lock(&vms->lock); 08084 if (vms->deleted) { 08085 /* Since we now expunge after each delete, deleting in reverse order 08086 * ensures that no reordering occurs between each step. */ 08087 last_msg_idx = vms->dh_arraysize; 08088 for (x = last_msg_idx - 1; x >= 0; x--) { 08089 if (vms->deleted[x]) { 08090 ast_debug(3, "IMAP delete of %d\n", x); 08091 DELETE(vms->curdir, x, vms->fn, vmu); 08092 } 08093 } 08094 } 08095 #endif 08096 08097 done: 08098 if (vms->deleted) { 08099 ast_free(vms->deleted); 08100 vms->deleted = NULL; 08101 } 08102 if (vms->heard) { 08103 ast_free(vms->heard); 08104 vms->heard = NULL; 08105 } 08106 vms->dh_arraysize = 0; 08107 #ifdef IMAP_STORAGE 08108 ast_mutex_unlock(&vms->lock); 08109 #endif 08110 08111 return 0; 08112 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 11103 of file app_voicemail.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
11104 { 11105 int which = 0; 11106 int wordlen; 11107 struct ast_vm_user *vmu; 11108 const char *context = ""; 11109 11110 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11111 if (pos > 4) 11112 return NULL; 11113 if (pos == 3) 11114 return (state == 0) ? ast_strdup("for") : NULL; 11115 wordlen = strlen(word); 11116 AST_LIST_TRAVERSE(&users, vmu, list) { 11117 if (!strncasecmp(word, vmu->context, wordlen)) { 11118 if (context && strcmp(context, vmu->context) && ++which > state) 11119 return ast_strdup(vmu->context); 11120 /* ignore repeated contexts ? */ 11121 context = vmu->context; 11122 } 11123 } 11124 return NULL; 11125 }
static int copy | ( | char * | infile, | |
char * | outfile | |||
) | [static] |
Utility function to copy a file.
infile | The path to the file to be copied. The file must be readable, it is opened in read only mode. | |
outfile | The path for which to copy the file to. The directory permissions must allow the creation (or truncation) of the file, and allow for opening the file in write only mode. |
When the compiler option HARDLINK_WHEN_POSSIBLE is set, the copy operation will attempt to use the hard link facility instead of copy the file (to save disk space). If the link operation fails, it falls back to the copy operation. The copy operation copies up to 4096 bytes at once.
Definition at line 4120 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, errno, and VOICEMAIL_FILE_MODE.
Referenced by ast_func_read(), ast_func_read2(), ast_func_write(), copy_plain_file(), iax2_register(), and vm_forwardoptions().
04121 { 04122 int ifd; 04123 int ofd; 04124 int res; 04125 int len; 04126 char buf[4096]; 04127 04128 #ifdef HARDLINK_WHEN_POSSIBLE 04129 /* Hard link if possible; saves disk space & is faster */ 04130 if (link(infile, outfile)) { 04131 #endif 04132 if ((ifd = open(infile, O_RDONLY)) < 0) { 04133 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04134 return -1; 04135 } 04136 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04137 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04138 close(ifd); 04139 return -1; 04140 } 04141 do { 04142 len = read(ifd, buf, sizeof(buf)); 04143 if (len < 0) { 04144 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04145 close(ifd); 04146 close(ofd); 04147 unlink(outfile); 04148 } else if (len) { 04149 res = write(ofd, buf, len); 04150 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04151 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04152 close(ifd); 04153 close(ofd); 04154 unlink(outfile); 04155 } 04156 } 04157 } while (len); 04158 close(ifd); 04159 close(ofd); 04160 return 0; 04161 #ifdef HARDLINK_WHEN_POSSIBLE 04162 } else { 04163 /* Hard link succeeded */ 04164 return 0; 04165 } 04166 #endif 04167 }
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, | |||
const char * | flag | |||
) | [static] |
Copies a message from one mailbox to another.
chan | ||
vmu | ||
imbox | ||
msgnum | ||
duration | ||
recip | ||
fmt | ||
dir | ||
flag | This is only used by file storage based mailboxes. |
Definition at line 5356 of file app_voicemail.c.
References ast_copy_string(), ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, ast_strlen_zero(), ast_unlock_path(), ast_channel::caller, ast_vm_user::context, COPY, copy_plain_file(), create_dirpath(), ERROR_LOCK_PATH, EXISTS, ast_party_caller::id, inprocess_count(), last_message_index(), ast_vm_user::mailbox, make_dir(), make_file(), maxmsg, mbox(), ast_party_id::name, notify_new_message(), ast_party_id::number, S_COR, STORE, ast_party_name::str, ast_party_number::str, ast_party_name::valid, ast_party_number::valid, vm_delete(), and vm_lock_path().
Referenced by forward_message(), and leave_voicemail().
05357 { 05358 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05359 const char *frombox = mbox(vmu, imbox); 05360 const char *userfolder; 05361 int recipmsgnum; 05362 int res = 0; 05363 05364 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05365 05366 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05367 userfolder = "Urgent"; 05368 } else { 05369 userfolder = "INBOX"; 05370 } 05371 05372 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05373 05374 if (!dir) 05375 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05376 else 05377 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05378 05379 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05380 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05381 05382 if (vm_lock_path(todir)) 05383 return ERROR_LOCK_PATH; 05384 05385 recipmsgnum = last_message_index(recip, todir) + 1; 05386 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05387 make_file(topath, sizeof(topath), todir, recipmsgnum); 05388 #ifndef ODBC_STORAGE 05389 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05390 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05391 } else { 05392 #endif 05393 /* If we are prepending a message for ODBC, then the message already 05394 * exists in the database, but we want to force copying from the 05395 * filesystem (since only the FS contains the prepend). */ 05396 copy_plain_file(frompath, topath); 05397 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05398 vm_delete(topath); 05399 #ifndef ODBC_STORAGE 05400 } 05401 #endif 05402 } else { 05403 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05404 res = -1; 05405 } 05406 ast_unlock_path(todir); 05407 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05408 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05409 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05410 flag); 05411 05412 return res; 05413 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Every voicemail has the data (.wav) file, and the information file. This function performs the file system copying of the information file for a voicemail, handling the internal fields and their values. This is used by the COPY macro when not using IMAP storage.
Definition at line 4178 of file app_voicemail.c.
References ast_check_realtime(), ast_filecopy(), ast_load_realtime(), ast_store_realtime(), ast_variables_destroy(), copy(), exten, ast_variable::name, ast_variable::next, SENTINEL, and ast_variable::value.
Referenced by copy_message().
04179 { 04180 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04181 struct ast_variable *tmp,*var = NULL; 04182 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04183 ast_filecopy(frompath, topath, NULL); 04184 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04185 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04186 if (ast_check_realtime("voicemail_data")) { 04187 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04188 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04189 for (tmp = var; tmp; tmp = tmp->next) { 04190 if (!strcasecmp(tmp->name, "origmailbox")) { 04191 origmailbox = tmp->value; 04192 } else if (!strcasecmp(tmp->name, "context")) { 04193 context = tmp->value; 04194 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04195 macrocontext = tmp->value; 04196 } else if (!strcasecmp(tmp->name, "exten")) { 04197 exten = tmp->value; 04198 } else if (!strcasecmp(tmp->name, "priority")) { 04199 priority = tmp->value; 04200 } else if (!strcasecmp(tmp->name, "callerchan")) { 04201 callerchan = tmp->value; 04202 } else if (!strcasecmp(tmp->name, "callerid")) { 04203 callerid = tmp->value; 04204 } else if (!strcasecmp(tmp->name, "origdate")) { 04205 origdate = tmp->value; 04206 } else if (!strcasecmp(tmp->name, "origtime")) { 04207 origtime = tmp->value; 04208 } else if (!strcasecmp(tmp->name, "category")) { 04209 category = tmp->value; 04210 } else if (!strcasecmp(tmp->name, "duration")) { 04211 duration = tmp->value; 04212 } 04213 } 04214 ast_store_realtime("voicemail_data", "filename", topath, "origmailbox", origmailbox, "context", context, "macrocontext", macrocontext, "exten", exten, "priority", priority, "callerchan", callerchan, "callerid", callerid, "origdate", origdate, "origtime", origtime, "category", category, "duration", duration, SENTINEL); 04215 } 04216 copy(frompath2, topath2); 04217 ast_variables_destroy(var); 04218 }
static int count_messages | ( | struct ast_vm_user * | vmu, | |
char * | dir | |||
) | [static] |
Find all .txt files - even if they are not in sequence from 0000.
vmu | ||
dir | This method is used when mailboxes are stored on the filesystem. (not ODBC and not IMAP). |
Definition at line 4015 of file app_voicemail.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
Referenced by leave_voicemail(), manager_list_voicemail_users(), and open_mailbox().
04016 { 04017 04018 int vmcount = 0; 04019 DIR *vmdir = NULL; 04020 struct dirent *vment = NULL; 04021 04022 if (vm_lock_path(dir)) 04023 return ERROR_LOCK_PATH; 04024 04025 if ((vmdir = opendir(dir))) { 04026 while ((vment = readdir(vmdir))) { 04027 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 04028 vmcount++; 04029 } 04030 } 04031 closedir(vmdir); 04032 } 04033 ast_unlock_path(dir); 04034 04035 return vmcount; 04036 }
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
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. |
Definition at line 1698 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
Referenced by add_email_attachment(), copy_message(), invent_message(), leave_voicemail(), open_mailbox(), and save_to_folder().
01699 { 01700 mode_t mode = VOICEMAIL_DIR_MODE; 01701 int res; 01702 01703 make_dir(dest, len, context, ext, folder); 01704 if ((res = ast_mkdir(dest, mode))) { 01705 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01706 return -1; 01707 } 01708 return 0; 01709 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 13132 of file app_voicemail.c.
References ast_copy_string(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_suite_event_notify, ast_verb, 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().
13133 { 13134 int cmd = 0; 13135 char destination[80] = ""; 13136 int retries = 0; 13137 13138 if (!num) { 13139 ast_verb(3, "Destination number will be entered manually\n"); 13140 while (retries < 3 && cmd != 't') { 13141 destination[1] = '\0'; 13142 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13143 if (!cmd) 13144 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13145 if (!cmd) 13146 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13147 if (!cmd) { 13148 cmd = ast_waitfordigit(chan, 6000); 13149 if (cmd) 13150 destination[0] = cmd; 13151 } 13152 if (!cmd) { 13153 retries++; 13154 } else { 13155 13156 if (cmd < 0) 13157 return 0; 13158 if (cmd == '*') { 13159 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13160 return 0; 13161 } 13162 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13163 retries++; 13164 else 13165 cmd = 't'; 13166 } 13167 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13168 } 13169 if (retries >= 3) { 13170 return 0; 13171 } 13172 13173 } else { 13174 if (option_verbose > 2) 13175 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13176 ast_copy_string(destination, num, sizeof(destination)); 13177 } 13178 13179 if (!ast_strlen_zero(destination)) { 13180 if (destination[strlen(destination) -1 ] == '*') 13181 return 0; 13182 if (option_verbose > 2) 13183 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13184 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13185 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13186 chan->priority = 0; 13187 return 9; 13188 } 13189 return 0; 13190 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static, read] |
Definition at line 10686 of file app_voicemail.c.
References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_strlen_zero(), ast_test_flag, ast_vm_user::context, globalflags, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
Referenced by actual_load_config(), and append_mailbox().
10687 { 10688 struct ast_vm_user *vmu; 10689 10690 if (!ast_strlen_zero(box) && box[0] == '*') { 10691 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10692 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10693 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10694 "\n\tand will be ignored.\n", box, context); 10695 return NULL; 10696 } 10697 10698 AST_LIST_TRAVERSE(&users, vmu, list) { 10699 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10700 if (strcasecmp(vmu->context, context)) { 10701 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10702 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10703 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10704 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10705 } 10706 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10707 return NULL; 10708 } 10709 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10710 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10711 return NULL; 10712 } 10713 } 10714 10715 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10716 return NULL; 10717 10718 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10719 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10720 10721 AST_LIST_INSERT_TAIL(&users, vmu, list); 10722 10723 return vmu; 10724 }
static struct ast_vm_user* find_user | ( | struct ast_vm_user * | ivm, | |
const char * | context, | |||
const char * | mailbox | |||
) | [static, read] |
Finds a voicemail user from the users file or the realtime engine.
ivm | ||
context | ||
mailbox |
Definition at line 1437 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_malloc, ast_set2_flag, ast_strdup, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, find_user_realtime(), globalflags, VM_ALLOCED, and VM_SEARCH.
Referenced by acf_mailbox_exists(), advanced_options(), forward_message(), leave_voicemail(), vm_authenticate(), vm_box_exists(), and vm_execmain().
01438 { 01439 /* This function could be made to generate one from a database, too */ 01440 struct ast_vm_user *vmu = NULL, *cur; 01441 AST_LIST_LOCK(&users); 01442 01443 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01444 context = "default"; 01445 01446 AST_LIST_TRAVERSE(&users, cur, list) { 01447 #ifdef IMAP_STORAGE 01448 if (cur->imapversion != imapversion) { 01449 continue; 01450 } 01451 #endif 01452 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01453 break; 01454 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01455 break; 01456 } 01457 if (cur) { 01458 /* Make a copy, so that on a reload, we have no race */ 01459 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01460 *vmu = *cur; 01461 if (!ivm) { 01462 vmu->emailbody = ast_strdup(cur->emailbody); 01463 vmu->emailsubject = ast_strdup(cur->emailsubject); 01464 } 01465 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01466 AST_LIST_NEXT(vmu, list) = NULL; 01467 } 01468 } else 01469 vmu = find_user_realtime(ivm, context, mailbox); 01470 AST_LIST_UNLOCK(&users); 01471 return vmu; 01472 }
static struct ast_vm_user* find_user_realtime | ( | struct ast_vm_user * | ivm, | |
const char * | context, | |||
const char * | mailbox | |||
) | [static, read] |
Finds a voicemail user from the realtime engine.
ivm | ||
context | ||
mailbox | This is called as a fall through case when the normal find_user() was not able to find a user. That is, the default it so look in the usual voicemail users file first. |
Definition at line 1396 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_user(), globalflags, ast_vm_user::mailbox, populate_defaults(), SENTINEL, var, VM_ALLOCED, and VM_SEARCH.
Referenced by find_user().
01397 { 01398 struct ast_variable *var; 01399 struct ast_vm_user *retval; 01400 01401 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01402 if (ivm) { 01403 memset(retval, 0, sizeof(*retval)); 01404 } 01405 populate_defaults(retval); 01406 if (!ivm) { 01407 ast_set_flag(retval, VM_ALLOCED); 01408 } 01409 if (mailbox) { 01410 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01411 } 01412 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) { 01413 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01414 } else { 01415 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01416 } 01417 if (var) { 01418 apply_options_full(retval, var); 01419 ast_variables_destroy(var); 01420 } else { 01421 if (!ivm) 01422 free_user(retval); 01423 retval = NULL; 01424 } 01425 } 01426 return retval; 01427 }
static int forward_message | ( | struct ast_channel * | chan, | |
char * | context, | |||
struct vm_state * | vms, | |||
struct ast_vm_user * | sender, | |||
char * | fmt, | |||
int | is_new_message, | |||
signed char | record_gain, | |||
int | urgent | |||
) | [static] |
Sends a voicemail message to a mailbox recipient.
chan | ||
context | ||
vms | ||
sender | ||
fmt | ||
is_new_message | Used to indicate the mode for which this method was invoked. Will be 0 when called to forward an existing message (option 8) Will be 1 when called to leave a message (option 3->5) | |
record_gain | ||
urgent | Reads the destination mailbox(es) from keypad input for CID, or if use_directory feature is enabled, the Directory. |
When in the leave message mode (is_new_message == 1):
When in the forward message mode (is_new_message == 0):
Definition at line 7206 of file app_voicemail.c.
References ast_clear_flag, ast_copy_string(), ast_fileexists(), ast_filerename(), 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_LOG_ERROR, AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_say_digit_str(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_waitfordigit(), ast_channel::caller, ast_vm_user::context, ast_channel::context, copy_message(), vm_state::curbox, vm_state::curdir, vm_state::curmsg, DISPOSE, ast_channel::exten, find_user(), vm_state::fn, free_user(), globalflags, ast_party_caller::id, inboxcount(), inprocess_count(), leave_voicemail(), LOG_ERROR, LOG_NOTICE, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_party_id::name, ast_party_id::number, pbx_exec(), pbx_findapp(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, run_externnotify(), S_COR, S_OR, sendmail(), serveremail, STORE, ast_party_name::str, ast_party_number::str, vm_state::username, ast_party_name::valid, ast_party_number::valid, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), VM_FWDURGAUTO, VM_SPOOL_DIR, and vmfmts.
Referenced by vm_execmain().
07207 { 07208 #ifdef IMAP_STORAGE 07209 int todircount = 0; 07210 struct vm_state *dstvms; 07211 #endif 07212 char username[70]=""; 07213 char fn[PATH_MAX]; /* for playback of name greeting */ 07214 char ecodes[16] = "#"; 07215 int res = 0, cmd = 0; 07216 struct ast_vm_user *receiver = NULL, *vmtmp; 07217 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07218 char *stringp; 07219 const char *s; 07220 int saved_messages = 0; 07221 int valid_extensions = 0; 07222 char *dir; 07223 int curmsg; 07224 char urgent_str[7] = ""; 07225 int prompt_played = 0; 07226 #ifndef IMAP_STORAGE 07227 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07228 #endif 07229 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07230 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07231 } 07232 07233 if (vms == NULL) return -1; 07234 dir = vms->curdir; 07235 curmsg = vms->curmsg; 07236 07237 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07238 while (!res && !valid_extensions) { 07239 int use_directory = 0; 07240 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07241 int done = 0; 07242 int retries = 0; 07243 cmd = 0; 07244 while ((cmd >= 0) && !done ){ 07245 if (cmd) 07246 retries = 0; 07247 switch (cmd) { 07248 case '1': 07249 use_directory = 0; 07250 done = 1; 07251 break; 07252 case '2': 07253 use_directory = 1; 07254 done = 1; 07255 break; 07256 case '*': 07257 cmd = 't'; 07258 done = 1; 07259 break; 07260 default: 07261 /* Press 1 to enter an extension press 2 to use the directory */ 07262 cmd = ast_play_and_wait(chan, "vm-forward"); 07263 if (!cmd) { 07264 cmd = ast_waitfordigit(chan, 3000); 07265 } 07266 if (!cmd) { 07267 retries++; 07268 } 07269 if (retries > 3) { 07270 cmd = 't'; 07271 done = 1; 07272 } 07273 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07274 } 07275 } 07276 if (cmd < 0 || cmd == 't') 07277 break; 07278 } 07279 07280 if (use_directory) { 07281 /* use app_directory */ 07282 07283 char old_context[sizeof(chan->context)]; 07284 char old_exten[sizeof(chan->exten)]; 07285 int old_priority; 07286 struct ast_app* directory_app; 07287 07288 directory_app = pbx_findapp("Directory"); 07289 if (directory_app) { 07290 char vmcontext[256]; 07291 /* make backup copies */ 07292 memcpy(old_context, chan->context, sizeof(chan->context)); 07293 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07294 old_priority = chan->priority; 07295 07296 /* call the the Directory, changes the channel */ 07297 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07298 res = pbx_exec(chan, directory_app, vmcontext); 07299 07300 ast_copy_string(username, chan->exten, sizeof(username)); 07301 07302 /* restore the old context, exten, and priority */ 07303 memcpy(chan->context, old_context, sizeof(chan->context)); 07304 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07305 chan->priority = old_priority; 07306 } else { 07307 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07308 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07309 } 07310 } else { 07311 /* Ask for an extension */ 07312 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07313 prompt_played++; 07314 if (res || prompt_played > 4) 07315 break; 07316 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07317 break; 07318 } 07319 07320 /* start all over if no username */ 07321 if (ast_strlen_zero(username)) 07322 continue; 07323 stringp = username; 07324 s = strsep(&stringp, "*"); 07325 /* start optimistic */ 07326 valid_extensions = 1; 07327 while (s) { 07328 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07329 int oldmsgs; 07330 int newmsgs; 07331 int capacity; 07332 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07333 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07334 /* Shouldn't happen, but allow trying another extension if it does */ 07335 res = ast_play_and_wait(chan, "pbx-invalid"); 07336 valid_extensions = 0; 07337 break; 07338 } 07339 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07340 if ((newmsgs + oldmsgs) >= capacity) { 07341 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07342 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07343 valid_extensions = 0; 07344 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07345 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07346 free_user(vmtmp); 07347 } 07348 inprocess_count(receiver->mailbox, receiver->context, -1); 07349 break; 07350 } 07351 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07352 } else { 07353 /* XXX Optimization for the future. When we encounter a single bad extension, 07354 * bailing out on all of the extensions may not be the way to go. We should 07355 * probably just bail on that single extension, then allow the user to enter 07356 * several more. XXX 07357 */ 07358 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07359 free_user(receiver); 07360 } 07361 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07362 /* "I am sorry, that's not a valid extension. Please try again." */ 07363 res = ast_play_and_wait(chan, "pbx-invalid"); 07364 valid_extensions = 0; 07365 break; 07366 } 07367 07368 /* play name if available, else play extension number */ 07369 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07370 RETRIEVE(fn, -1, s, receiver->context); 07371 if (ast_fileexists(fn, NULL, NULL) > 0) { 07372 res = ast_stream_and_wait(chan, fn, ecodes); 07373 if (res) { 07374 DISPOSE(fn, -1); 07375 return res; 07376 } 07377 } else { 07378 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07379 } 07380 DISPOSE(fn, -1); 07381 07382 s = strsep(&stringp, "*"); 07383 } 07384 /* break from the loop of reading the extensions */ 07385 if (valid_extensions) 07386 break; 07387 } 07388 /* check if we're clear to proceed */ 07389 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07390 return res; 07391 if (is_new_message == 1) { 07392 struct leave_vm_options leave_options; 07393 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07394 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07395 07396 /* Send VoiceMail */ 07397 memset(&leave_options, 0, sizeof(leave_options)); 07398 leave_options.record_gain = record_gain; 07399 cmd = leave_voicemail(chan, mailbox, &leave_options); 07400 } else { 07401 /* Forward VoiceMail */ 07402 long duration = 0; 07403 struct vm_state vmstmp; 07404 int copy_msg_result = 0; 07405 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07406 07407 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07408 07409 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07410 if (!cmd) { 07411 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07412 #ifdef IMAP_STORAGE 07413 int attach_user_voicemail; 07414 char *myserveremail = serveremail; 07415 07416 /* get destination mailbox */ 07417 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07418 if (!dstvms) { 07419 dstvms = create_vm_state_from_user(vmtmp); 07420 } 07421 if (dstvms) { 07422 init_mailstream(dstvms, 0); 07423 if (!dstvms->mailstream) { 07424 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07425 } else { 07426 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07427 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07428 } 07429 } else { 07430 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07431 } 07432 if (!ast_strlen_zero(vmtmp->serveremail)) 07433 myserveremail = vmtmp->serveremail; 07434 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07435 /* NULL category for IMAP storage */ 07436 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07437 dstvms->curbox, 07438 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07439 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07440 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07441 NULL, urgent_str); 07442 #else 07443 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07444 #endif 07445 saved_messages++; 07446 AST_LIST_REMOVE_CURRENT(list); 07447 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07448 free_user(vmtmp); 07449 if (res) 07450 break; 07451 } 07452 AST_LIST_TRAVERSE_SAFE_END; 07453 if (saved_messages > 0 && !copy_msg_result) { 07454 /* give confirmation that the message was saved */ 07455 /* commented out since we can't forward batches yet 07456 if (saved_messages == 1) 07457 res = ast_play_and_wait(chan, "vm-message"); 07458 else 07459 res = ast_play_and_wait(chan, "vm-messages"); 07460 if (!res) 07461 res = ast_play_and_wait(chan, "vm-saved"); */ 07462 #ifdef IMAP_STORAGE 07463 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07464 if (ast_strlen_zero(vmstmp.introfn)) 07465 #endif 07466 res = ast_play_and_wait(chan, "vm-msgsaved"); 07467 } 07468 #ifndef IMAP_STORAGE 07469 else { 07470 /* with IMAP, mailbox full warning played by imap_check_limits */ 07471 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07472 } 07473 /* Restore original message without prepended message if backup exists */ 07474 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07475 strcpy(textfile, msgfile); 07476 strcpy(backup, msgfile); 07477 strcpy(backup_textfile, msgfile); 07478 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07479 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07480 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07481 if (ast_fileexists(backup, NULL, NULL) > 0) { 07482 ast_filerename(backup, msgfile, NULL); 07483 rename(backup_textfile, textfile); 07484 } 07485 #endif 07486 } 07487 DISPOSE(dir, curmsg); 07488 #ifndef IMAP_STORAGE 07489 if (cmd) { /* assuming hangup, cleanup backup file */ 07490 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07491 strcpy(textfile, msgfile); 07492 strcpy(backup_textfile, msgfile); 07493 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07494 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07495 rename(backup_textfile, textfile); 07496 } 07497 #endif 07498 } 07499 07500 /* If anything failed above, we still have this list to free */ 07501 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07502 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07503 free_user(vmtmp); 07504 } 07505 return res ? res : cmd; 07506 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1753 of file app_voicemail.c.
References ast_free, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, and VM_ALLOCED.
Referenced by AST_TEST_DEFINE(), find_user_realtime(), forward_message(), free_vm_users(), leave_voicemail(), and vm_execmain().
01754 { 01755 if (ast_test_flag(vmu, VM_ALLOCED)) { 01756 01757 ast_free(vmu->emailbody); 01758 vmu->emailbody = NULL; 01759 01760 ast_free(vmu->emailsubject); 01761 vmu->emailsubject = NULL; 01762 01763 ast_free(vmu); 01764 } 01765 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11715 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_set_flag, free_user(), and VM_ALLOCED.
Referenced by actual_load_config(), and unload_module().
11716 { 11717 struct ast_vm_user *current; 11718 AST_LIST_LOCK(&users); 11719 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11720 ast_set_flag(current, VM_ALLOCED); 11721 free_user(current); 11722 } 11723 AST_LIST_UNLOCK(&users); 11724 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11727 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free_zone().
Referenced by actual_load_config(), and unload_module().
11728 { 11729 struct vm_zone *zcur; 11730 AST_LIST_LOCK(&zones); 11731 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11732 free_zone(zcur); 11733 AST_LIST_UNLOCK(&zones); 11734 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5124 of file app_voicemail.c.
References ast_free.
Referenced by free_vm_zones().
05125 { 05126 ast_free(z); 05127 }
static int get_date | ( | char * | s, | |
int | len | |||
) | [static] |
Gets the current date and time, as formatted string.
s | The buffer to hold the output formatted date. | |
len | the length of the buffer. Used to prevent buffer overflow in ast_strftime. |
The date format string used is "%a %b %e %r UTC %Y".
Definition at line 5080 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail().
05081 { 05082 struct ast_tm tm; 05083 struct timeval t = ast_tvnow(); 05084 05085 ast_localtime(&t, &tm, "UTC"); 05086 05087 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05088 }
static int get_folder | ( | struct ast_channel * | chan, | |
int | start | |||
) | [static] |
get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized
Definition at line 6815 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_fileexists(), ast_play_and_wait(), ast_say_number(), ast_test_suite_event_notify, ast_verb, ast_waitfordigit(), mbox(), and vm_play_folder_name().
Referenced by get_folder2().
06816 { 06817 int x; 06818 int d; 06819 char fn[PATH_MAX]; 06820 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06821 if (d) 06822 return d; 06823 for (x = start; x < 5; x++) { /* For all folders */ 06824 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06825 return d; 06826 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06827 if (d) 06828 return d; 06829 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06830 06831 /* The inbox folder can have its name changed under certain conditions 06832 * so this checks if the sound file exists for the inbox folder name and 06833 * if it doesn't, plays the default name instead. */ 06834 if (x == 0) { 06835 if (ast_fileexists(fn, NULL, NULL)) { 06836 d = vm_play_folder_name(chan, fn); 06837 } else { 06838 ast_verb(1, "failed to find %s\n", fn); 06839 d = vm_play_folder_name(chan, "vm-INBOX"); 06840 } 06841 } else { 06842 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06843 d = vm_play_folder_name(chan, fn); 06844 } 06845 06846 if (d) 06847 return d; 06848 d = ast_waitfordigit(chan, 500); 06849 if (d) 06850 return d; 06851 } 06852 06853 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06854 if (d) 06855 return d; 06856 d = ast_waitfordigit(chan, 4000); 06857 return d; 06858 }
static int get_folder2 | ( | struct ast_channel * | chan, | |
char * | fn, | |||
int | start | |||
) | [static] |
plays a prompt and waits for a keypress.
chan | ||
fn | the name of the voice prompt file to be played. For example, 'vm-changeto', 'vm-savefolder' | |
start | Does not appear to be used at this time. |
This is used by the main menu option to move a message to a folder or to save a message into a folder. After playing the message identified by the fn parameter value, it calls get_folder(), which plays the prompting for the number inputs that correspond to the available folders.
Definition at line 6872 of file app_voicemail.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
Referenced by vm_execmain().
06873 { 06874 int res = 0; 06875 int loops = 0; 06876 06877 res = ast_play_and_wait(chan, fn); /* Folder name */ 06878 while (((res < '0') || (res > '9')) && 06879 (res != '#') && (res >= 0) && 06880 loops < 4) { 06881 res = get_folder(chan, 0); 06882 loops++; 06883 } 06884 if (loops == 4) { /* give up */ 06885 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06886 return '#'; 06887 } 06888 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06889 return res; 06890 }
static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1740 of file app_voicemail.c.
References ARRAY_LEN, and mailbox_folders.
Referenced by vm_execmain().
01741 { 01742 size_t i; 01743 01744 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01745 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01746 return i; 01747 } 01748 } 01749 01750 return -1; 01751 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11485 of file app_voicemail.c.
References ast_calloc, ast_free, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), mwi_sub_task::context, mwi_sub_task::mailbox, poll_subscribed_mailbox(), and mwi_sub_task::uniqueid.
Referenced by mwi_sub_event_cb().
11486 { 11487 unsigned int len; 11488 struct mwi_sub *mwi_sub; 11489 struct mwi_sub_task *p = datap; 11490 11491 len = sizeof(*mwi_sub); 11492 if (!ast_strlen_zero(p->mailbox)) 11493 len += strlen(p->mailbox); 11494 11495 if (!ast_strlen_zero(p->context)) 11496 len += strlen(p->context) + 1; /* Allow for seperator */ 11497 11498 if (!(mwi_sub = ast_calloc(1, len))) 11499 return -1; 11500 11501 mwi_sub->uniqueid = p->uniqueid; 11502 if (!ast_strlen_zero(p->mailbox)) 11503 strcpy(mwi_sub->mailbox, p->mailbox); 11504 11505 if (!ast_strlen_zero(p->context)) { 11506 strcat(mwi_sub->mailbox, "@"); 11507 strcat(mwi_sub->mailbox, p->context); 11508 } 11509 11510 AST_RWLIST_WRLOCK(&mwi_subs); 11511 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11512 AST_RWLIST_UNLOCK(&mwi_subs); 11513 ast_free((void *) p->mailbox); 11514 ast_free((void *) p->context); 11515 ast_free(p); 11516 poll_subscribed_mailbox(mwi_sub); 11517 return 0; 11518 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11463 of file app_voicemail.c.
References ast_free, AST_LIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and mwi_sub_destroy().
Referenced by mwi_unsub_event_cb().
11464 { 11465 struct mwi_sub *mwi_sub; 11466 uint32_t *uniqueid = datap; 11467 11468 AST_RWLIST_WRLOCK(&mwi_subs); 11469 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11470 if (mwi_sub->uniqueid == *uniqueid) { 11471 AST_LIST_REMOVE_CURRENT(entry); 11472 break; 11473 } 11474 } 11475 AST_RWLIST_TRAVERSE_SAFE_END 11476 AST_RWLIST_UNLOCK(&mwi_subs); 11477 11478 if (mwi_sub) 11479 mwi_sub_destroy(mwi_sub); 11480 11481 ast_free(uniqueid); 11482 return 0; 11483 }
static char* handle_voicemail_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Reload voicemail configuration from the CLI.
Definition at line 11240 of file app_voicemail.c.
References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, load_config(), and ast_cli_entry::usage.
11241 { 11242 switch (cmd) { 11243 case CLI_INIT: 11244 e->command = "voicemail reload"; 11245 e->usage = 11246 "Usage: voicemail reload\n" 11247 " Reload voicemail configuration\n"; 11248 return NULL; 11249 case CLI_GENERATE: 11250 return NULL; 11251 } 11252 11253 if (a->argc != 2) 11254 return CLI_SHOWUSAGE; 11255 11256 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11257 load_config(1); 11258 11259 return CLI_SUCCESS; 11260 }
static char* handle_voicemail_show_users | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Show a list of voicemail users in the CLI.
Definition at line 11128 of file app_voicemail.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_check_realtime(), ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_voicemail_show_users(), ast_vm_user::context, ast_cli_args::fd, ast_vm_user::fullname, HVSU_OUTPUT_FORMAT, inboxcount(), ast_cli_args::line, ast_vm_user::mailbox, ast_cli_args::n, ast_cli_args::pos, show_users_realtime(), ast_cli_entry::usage, ast_cli_args::word, and ast_vm_user::zonetag.
11129 { 11130 struct ast_vm_user *vmu; 11131 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11132 const char *context = NULL; 11133 int users_counter = 0; 11134 11135 switch (cmd) { 11136 case CLI_INIT: 11137 e->command = "voicemail show users"; 11138 e->usage = 11139 "Usage: voicemail show users [for <context>]\n" 11140 " Lists all mailboxes currently set up\n"; 11141 return NULL; 11142 case CLI_GENERATE: 11143 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11144 } 11145 11146 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11147 return CLI_SHOWUSAGE; 11148 if (a->argc == 5) { 11149 if (strcmp(a->argv[3],"for")) 11150 return CLI_SHOWUSAGE; 11151 context = a->argv[4]; 11152 } 11153 11154 if (ast_check_realtime("voicemail")) { 11155 if (!context) { 11156 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11157 return CLI_SHOWUSAGE; 11158 } 11159 return show_users_realtime(a->fd, context); 11160 } 11161 11162 AST_LIST_LOCK(&users); 11163 if (AST_LIST_EMPTY(&users)) { 11164 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11165 AST_LIST_UNLOCK(&users); 11166 return CLI_FAILURE; 11167 } 11168 if (!context) { 11169 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11170 } else { 11171 int count = 0; 11172 AST_LIST_TRAVERSE(&users, vmu, list) { 11173 if (!strcmp(context, vmu->context)) { 11174 count++; 11175 break; 11176 } 11177 } 11178 if (count) { 11179 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11180 } else { 11181 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11182 AST_LIST_UNLOCK(&users); 11183 return CLI_FAILURE; 11184 } 11185 } 11186 AST_LIST_TRAVERSE(&users, vmu, list) { 11187 int newmsgs = 0, oldmsgs = 0; 11188 char count[12], tmp[256] = ""; 11189 11190 if (!context || !strcmp(context, vmu->context)) { 11191 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11192 inboxcount(tmp, &newmsgs, &oldmsgs); 11193 snprintf(count, sizeof(count), "%d", newmsgs); 11194 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11195 users_counter++; 11196 } 11197 } 11198 AST_LIST_UNLOCK(&users); 11199 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11200 return CLI_SUCCESS; 11201 }
static char* handle_voicemail_show_zones | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Show a list of voicemail zones in the CLI.
Definition at line 11204 of file app_voicemail.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HVSZ_OUTPUT_FORMAT, and ast_cli_entry::usage.
11205 { 11206 struct vm_zone *zone; 11207 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11208 char *res = CLI_SUCCESS; 11209 11210 switch (cmd) { 11211 case CLI_INIT: 11212 e->command = "voicemail show zones"; 11213 e->usage = 11214 "Usage: voicemail show zones\n" 11215 " Lists zone message formats\n"; 11216 return NULL; 11217 case CLI_GENERATE: 11218 return NULL; 11219 } 11220 11221 if (a->argc != 3) 11222 return CLI_SHOWUSAGE; 11223 11224 AST_LIST_LOCK(&zones); 11225 if (!AST_LIST_EMPTY(&zones)) { 11226 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11227 AST_LIST_TRAVERSE(&zones, zone, list) { 11228 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11229 } 11230 } else { 11231 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11232 res = CLI_FAILURE; 11233 } 11234 AST_LIST_UNLOCK(&zones); 11235 11236 return res; 11237 }
static int has_voicemail | ( | const char * | mailbox, | |
const char * | folder | |||
) | [static] |
Determines if the given folder has messages.
mailbox | The @ delimited string for user. If no context is found, uses 'default' for the context. | |
folder | the folder to look in |
This function is used when the mailbox is stored in a filesystem back end. This invokes the __has_voicemail(). Here we are interested in the presence of messages (> 0) only, not the actual count.
Definition at line 5468 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), and ast_strlen_zero().
Referenced by load_module(), and vm_execmain().
05469 { 05470 char tmp[256], *tmp2 = tmp, *box, *context; 05471 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05472 if (ast_strlen_zero(folder)) { 05473 folder = "INBOX"; 05474 } 05475 while ((box = strsep(&tmp2, ",&"))) { 05476 if ((context = strchr(box, '@'))) 05477 *context++ = '\0'; 05478 else 05479 context = "default"; 05480 if (__has_voicemail(context, box, folder, 1)) 05481 return 1; 05482 /* If we are checking INBOX, we should check Urgent as well */ 05483 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05484 return 1; 05485 } 05486 } 05487 return 0; 05488 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5550 of file app_voicemail.c.
References inboxcount2().
Referenced by forward_message(), handle_voicemail_show_users(), leave_voicemail(), load_module(), and manager_list_voicemail_users().
05551 { 05552 int urgentmsgs = 0; 05553 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05554 if (newmsgs) { 05555 *newmsgs += urgentmsgs; 05556 } 05557 return res; 05558 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5491 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), and ast_strlen_zero().
Referenced by append_mailbox(), inboxcount(), load_module(), poll_subscribed_mailbox(), run_externnotify(), and vm_users_data_provider_get_helper().
05492 { 05493 char tmp[256]; 05494 char *context; 05495 05496 /* If no mailbox, return immediately */ 05497 if (ast_strlen_zero(mailbox)) 05498 return 0; 05499 05500 if (newmsgs) 05501 *newmsgs = 0; 05502 if (oldmsgs) 05503 *oldmsgs = 0; 05504 if (urgentmsgs) 05505 *urgentmsgs = 0; 05506 05507 if (strchr(mailbox, ',')) { 05508 int tmpnew, tmpold, tmpurgent; 05509 char *mb, *cur; 05510 05511 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05512 mb = tmp; 05513 while ((cur = strsep(&mb, ", "))) { 05514 if (!ast_strlen_zero(cur)) { 05515 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05516 return -1; 05517 else { 05518 if (newmsgs) 05519 *newmsgs += tmpnew; 05520 if (oldmsgs) 05521 *oldmsgs += tmpold; 05522 if (urgentmsgs) 05523 *urgentmsgs += tmpurgent; 05524 } 05525 } 05526 } 05527 return 0; 05528 } 05529 05530 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05531 05532 if ((context = strchr(tmp, '@'))) 05533 *context++ = '\0'; 05534 else 05535 context = "default"; 05536 05537 if (newmsgs) 05538 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05539 if (oldmsgs) 05540 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05541 if (urgentmsgs) 05542 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05543 05544 return 0; 05545 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4250 of file app_voicemail.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by ast_eivr_getvariable(), ast_eivr_setvariable(), inchar(), netconsole(), sip_addheader(), and sip_removeheader().
04251 { 04252 int l; 04253 04254 if (bio->ateof) 04255 return 0; 04256 04257 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04258 if (ferror(fi)) 04259 return -1; 04260 04261 bio->ateof = 1; 04262 return 0; 04263 } 04264 04265 bio->iolen = l; 04266 bio->iocp = 0; 04267 04268 return 1; 04269 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4274 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
static int inprocess_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 935 of file app_voicemail.c.
References CMP_MATCH, inprocess::context, and inprocess::mailbox.
Referenced by load_module().
static int inprocess_count | ( | const char * | context, | |
const char * | mailbox, | |||
int | delta | |||
) | [static] |
Definition at line 944 of file app_voicemail.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_alloca, ast_atomic_fetchadd_int(), ast_log(), inprocess::context, inprocess::count, inprocess_container, LOG_WARNING, and inprocess::mailbox.
Referenced by copy_message(), forward_message(), and leave_voicemail().
00945 { 00946 struct inprocess *i, *arg = ast_alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 00947 arg->context = arg->mailbox + strlen(mailbox) + 1; 00948 strcpy(arg->mailbox, mailbox); /* SAFE */ 00949 strcpy(arg->context, context); /* SAFE */ 00950 ao2_lock(inprocess_container); 00951 if ((i = ao2_find(inprocess_container, arg, 0))) { 00952 int ret = ast_atomic_fetchadd_int(&i->count, delta); 00953 ao2_unlock(inprocess_container); 00954 ao2_ref(i, -1); 00955 return ret; 00956 } 00957 if (delta < 0) { 00958 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 00959 } 00960 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 00961 ao2_unlock(inprocess_container); 00962 return 0; 00963 } 00964 i->context = i->mailbox + strlen(mailbox) + 1; 00965 strcpy(i->mailbox, mailbox); /* SAFE */ 00966 strcpy(i->context, context); /* SAFE */ 00967 i->count = delta; 00968 ao2_link(inprocess_container, i); 00969 ao2_unlock(inprocess_container); 00970 ao2_ref(i, -1); 00971 return 0; 00972 }
static int inprocess_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 929 of file app_voicemail.c.
References inprocess::mailbox.
Referenced by load_module().
static int invent_message | ( | struct ast_channel * | chan, | |
char * | context, | |||
char * | ext, | |||
int | busy, | |||
char * | ecodes | |||
) | [static] |
Definition at line 5090 of file app_voicemail.c.
References ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, RETRIEVE, and VM_SPOOL_DIR.
Referenced by leave_voicemail().
05091 { 05092 int res; 05093 char fn[PATH_MAX]; 05094 char dest[PATH_MAX]; 05095 05096 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05097 05098 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05099 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05100 return -1; 05101 } 05102 05103 RETRIEVE(fn, -1, ext, context); 05104 if (ast_fileexists(fn, NULL, NULL) > 0) { 05105 res = ast_stream_and_wait(chan, fn, ecodes); 05106 if (res) { 05107 DISPOSE(fn, -1); 05108 return res; 05109 } 05110 } else { 05111 /* Dispose just in case */ 05112 DISPOSE(fn, -1); 05113 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05114 if (res) 05115 return res; 05116 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 05117 if (res) 05118 return res; 05119 } 05120 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05121 return res; 05122 }
static int is_valid_dtmf | ( | const char * | key | ) | [static] |
Determines if a DTMF key entered is valid.
key | The character to be compared. expects a single character. Though is capable of handling a string, this is internally copies using ast_strdupa. |
Tests the character entered against the set of valid DTMF characters.
Definition at line 1371 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by actual_load_config().
01372 { 01373 int i; 01374 char *local_key = ast_strdupa(key); 01375 01376 for (i = 0; i < strlen(key); ++i) { 01377 if (!strchr(VALID_DTMF, *local_key)) { 01378 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01379 return 0; 01380 } 01381 local_key++; 01382 } 01383 return 1; 01384 }
static int last_message_index | ( | struct ast_vm_user * | vmu, | |
char * | dir | |||
) | [static] |
Determines the highest message number in use for a given user and mailbox folder.
vmu | ||
dir | the folder the mailbox folder to look for messages. Used to construct the SQL where clause. |
This method is used when mailboxes are stored on the filesystem. (not ODBC and not IMAP). Typical use to set the msgnum would be to take the value returned from this method and add one to it.
Definition at line 4069 of file app_voicemail.c.
References ast_debug, map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
Referenced by close_mailbox(), copy_message(), leave_voicemail(), open_mailbox(), and save_to_folder().
04070 { 04071 int x; 04072 unsigned char map[MAXMSGLIMIT] = ""; 04073 DIR *msgdir; 04074 struct dirent *msgdirent; 04075 int msgdirint; 04076 char extension[4]; 04077 int stopcount = 0; 04078 04079 /* Reading the entire directory into a file map scales better than 04080 * doing a stat repeatedly on a predicted sequence. I suspect this 04081 * is partially due to stat(2) internally doing a readdir(2) itself to 04082 * find each file. */ 04083 if (!(msgdir = opendir(dir))) { 04084 return -1; 04085 } 04086 04087 while ((msgdirent = readdir(msgdir))) { 04088 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04089 map[msgdirint] = 1; 04090 stopcount++; 04091 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04092 } 04093 } 04094 closedir(msgdir); 04095 04096 for (x = 0; x < vmu->maxmsg; x++) { 04097 if (map[x] == 1) { 04098 stopcount--; 04099 } else if (map[x] == 0 && !stopcount) { 04100 break; 04101 } 04102 } 04103 04104 return x - 1; 04105 }
static int leave_voicemail | ( | struct ast_channel * | chan, | |
char * | ext, | |||
struct leave_vm_options * | options | |||
) | [static] |
Prompts the user and records a voicemail to a mailbox.
chan | ||
ext | ||
options | OPT_BUSY_GREETING, OPT_UNAVAIL_GREETING |
Definition at line 5626 of file app_voicemail.c.
References ast_callerid_merge(), ast_canmatch_extension(), ast_channel_lock, ast_channel_unlock, ast_check_realtime(), ast_copy_string(), ast_debug, ast_destroy_realtime(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_free, ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_store_realtime(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strdupa, ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_update_realtime(), ast_verb, ast_waitstream(), ast_channel::caller, ast_channel::context, ast_vm_user::context, copy_message(), count_messages(), create_dirpath(), DISPOSE, errno, ast_vm_user::exit, leave_vm_options::exitcontext, exten, ast_channel::exten, find_user(), free_user(), ast_party_redirecting::from, get_date(), ast_party_caller::id, inboxcount(), inprocess_count(), INTRO, invent_message(), last_message_index(), LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, my_umask, ast_party_id::name, vm_state::newmessages, notify_new_message(), ast_party_id::number, OPERATOR_EXIT, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_SILENT, OPT_UNAVAIL_GREETING, option_debug, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, leave_vm_options::record_gain, ast_channel::redirecting, RENAME, RETRIEVE, S_COR, S_OR, SENTINEL, STORE, ast_party_name::str, ast_party_number::str, transfer, ast_party_name::valid, ast_party_number::valid, vm_lock_path(), VM_OPERATOR, VM_SPOOL_DIR, vmfmts, VOICEMAIL_DIR_MODE, and VOICEMAIL_FILE_MODE.
Referenced by advanced_options(), forward_message(), and vm_exec().
05627 { 05628 #ifdef IMAP_STORAGE 05629 int newmsgs, oldmsgs; 05630 #else 05631 char urgdir[PATH_MAX]; 05632 #endif 05633 char txtfile[PATH_MAX]; 05634 char tmptxtfile[PATH_MAX]; 05635 struct vm_state *vms = NULL; 05636 char callerid[256]; 05637 FILE *txt; 05638 char date[256]; 05639 int txtdes; 05640 int res = 0; 05641 int msgnum; 05642 int duration = 0; 05643 int sound_duration = 0; 05644 int ausemacro = 0; 05645 int ousemacro = 0; 05646 int ouseexten = 0; 05647 char tmpdur[16]; 05648 char priority[16]; 05649 char origtime[16]; 05650 char dir[PATH_MAX]; 05651 char tmpdir[PATH_MAX]; 05652 char fn[PATH_MAX]; 05653 char prefile[PATH_MAX] = ""; 05654 char tempfile[PATH_MAX] = ""; 05655 char ext_context[256] = ""; 05656 char fmt[80]; 05657 char *context; 05658 char ecodes[17] = "#"; 05659 struct ast_str *tmp = ast_str_create(16); 05660 char *tmpptr; 05661 struct ast_vm_user *vmu; 05662 struct ast_vm_user svm; 05663 const char *category = NULL; 05664 const char *code; 05665 const char *alldtmf = "0123456789ABCD*#"; 05666 char flag[80]; 05667 05668 if (!tmp) { 05669 return -1; 05670 } 05671 05672 ast_str_set(&tmp, 0, "%s", ext); 05673 ext = ast_str_buffer(tmp); 05674 if ((context = strchr(ext, '@'))) { 05675 *context++ = '\0'; 05676 tmpptr = strchr(context, '&'); 05677 } else { 05678 tmpptr = strchr(ext, '&'); 05679 } 05680 05681 if (tmpptr) 05682 *tmpptr++ = '\0'; 05683 05684 ast_channel_lock(chan); 05685 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05686 category = ast_strdupa(category); 05687 } 05688 ast_channel_unlock(chan); 05689 05690 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05691 ast_copy_string(flag, "Urgent", sizeof(flag)); 05692 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05693 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05694 } else { 05695 flag[0] = '\0'; 05696 } 05697 05698 ast_debug(3, "Before find_user\n"); 05699 if (!(vmu = find_user(&svm, context, ext))) { 05700 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05701 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05702 ast_free(tmp); 05703 return res; 05704 } 05705 /* Setup pre-file if appropriate */ 05706 if (strcmp(vmu->context, "default")) 05707 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05708 else 05709 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05710 05711 /* Set the path to the prefile. Will be one of 05712 VM_SPOOL_DIRcontext/ext/busy 05713 VM_SPOOL_DIRcontext/ext/unavail 05714 Depending on the flag set in options. 05715 */ 05716 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05717 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05718 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05719 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05720 } 05721 /* Set the path to the tmpfile as 05722 VM_SPOOL_DIR/context/ext/temp 05723 and attempt to create the folder structure. 05724 */ 05725 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05726 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05727 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05728 ast_free(tmp); 05729 return -1; 05730 } 05731 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05732 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05733 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05734 05735 DISPOSE(tempfile, -1); 05736 /* It's easier just to try to make it than to check for its existence */ 05737 #ifndef IMAP_STORAGE 05738 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05739 #else 05740 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05741 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05742 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05743 } 05744 #endif 05745 05746 /* Check current or macro-calling context for special extensions */ 05747 if (ast_test_flag(vmu, VM_OPERATOR)) { 05748 if (!ast_strlen_zero(vmu->exit)) { 05749 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05750 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05751 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05752 ouseexten = 1; 05753 } 05754 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05755 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05756 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05757 ouseexten = 1; 05758 } else if (!ast_strlen_zero(chan->macrocontext) 05759 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05760 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05761 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05762 ousemacro = 1; 05763 } 05764 } 05765 05766 if (!ast_strlen_zero(vmu->exit)) { 05767 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05768 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05769 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05770 } 05771 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05772 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05773 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05774 } else if (!ast_strlen_zero(chan->macrocontext) 05775 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05776 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05777 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05778 ausemacro = 1; 05779 } 05780 05781 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05782 for (code = alldtmf; *code; code++) { 05783 char e[2] = ""; 05784 e[0] = *code; 05785 if (strchr(ecodes, e[0]) == NULL 05786 && ast_canmatch_extension(chan, 05787 (!ast_strlen_zero(options->exitcontext) ? options->exitcontext : chan->context), 05788 e, 1, S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05789 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05790 } 05791 } 05792 } 05793 05794 /* Play the beginning intro if desired */ 05795 if (!ast_strlen_zero(prefile)) { 05796 #ifdef ODBC_STORAGE 05797 int success = 05798 #endif 05799 RETRIEVE(prefile, -1, ext, context); 05800 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05801 if (ast_streamfile(chan, prefile, chan->language) > -1) 05802 res = ast_waitstream(chan, ecodes); 05803 #ifdef ODBC_STORAGE 05804 if (success == -1) { 05805 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05806 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05807 store_file(prefile, vmu->mailbox, vmu->context, -1); 05808 } 05809 #endif 05810 } else { 05811 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05812 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05813 } 05814 DISPOSE(prefile, -1); 05815 if (res < 0) { 05816 ast_debug(1, "Hang up during prefile playback\n"); 05817 free_user(vmu); 05818 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05819 ast_free(tmp); 05820 return -1; 05821 } 05822 } 05823 if (res == '#') { 05824 /* On a '#' we skip the instructions */ 05825 ast_set_flag(options, OPT_SILENT); 05826 res = 0; 05827 } 05828 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05829 if (vmu->maxmsg == 0) { 05830 if (option_debug > 2) 05831 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05832 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05833 goto leave_vm_out; 05834 } 05835 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05836 res = ast_stream_and_wait(chan, INTRO, ecodes); 05837 if (res == '#') { 05838 ast_set_flag(options, OPT_SILENT); 05839 res = 0; 05840 } 05841 } 05842 if (res > 0) 05843 ast_stopstream(chan); 05844 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05845 other than the operator -- an automated attendant or mailbox login for example */ 05846 if (res == '*') { 05847 chan->exten[0] = 'a'; 05848 chan->exten[1] = '\0'; 05849 if (!ast_strlen_zero(vmu->exit)) { 05850 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05851 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05852 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05853 } 05854 chan->priority = 0; 05855 free_user(vmu); 05856 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05857 ast_free(tmp); 05858 return 0; 05859 } 05860 05861 /* Check for a '0' here */ 05862 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05863 transfer: 05864 if (ouseexten || ousemacro) { 05865 chan->exten[0] = 'o'; 05866 chan->exten[1] = '\0'; 05867 if (!ast_strlen_zero(vmu->exit)) { 05868 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05869 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05870 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05871 } 05872 ast_play_and_wait(chan, "transfer"); 05873 chan->priority = 0; 05874 free_user(vmu); 05875 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05876 } 05877 ast_free(tmp); 05878 return OPERATOR_EXIT; 05879 } 05880 05881 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05882 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05883 if (!ast_strlen_zero(options->exitcontext)) { 05884 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05885 } 05886 free_user(vmu); 05887 ast_free(tmp); 05888 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05889 return res; 05890 } 05891 05892 if (res < 0) { 05893 free_user(vmu); 05894 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05895 ast_free(tmp); 05896 return -1; 05897 } 05898 /* The meat of recording the message... All the announcements and beeps have been played*/ 05899 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05900 if (!ast_strlen_zero(fmt)) { 05901 msgnum = 0; 05902 05903 #ifdef IMAP_STORAGE 05904 /* Is ext a mailbox? */ 05905 /* must open stream for this user to get info! */ 05906 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05907 if (res < 0) { 05908 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05909 ast_free(tmp); 05910 return -1; 05911 } 05912 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05913 /* It is possible under certain circumstances that inboxcount did not 05914 * create a vm_state when it was needed. This is a catchall which will 05915 * rarely be used. 05916 */ 05917 if (!(vms = create_vm_state_from_user(vmu))) { 05918 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05919 ast_free(tmp); 05920 return -1; 05921 } 05922 } 05923 vms->newmessages++; 05924 05925 /* here is a big difference! We add one to it later */ 05926 msgnum = newmsgs + oldmsgs; 05927 ast_debug(3, "Messagecount set to %d\n", msgnum); 05928 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05929 /* set variable for compatibility */ 05930 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05931 05932 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05933 goto leave_vm_out; 05934 } 05935 #else 05936 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05937 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05938 if (!res) 05939 res = ast_waitstream(chan, ""); 05940 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05941 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05942 inprocess_count(vmu->mailbox, vmu->context, -1); 05943 goto leave_vm_out; 05944 } 05945 05946 #endif 05947 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05948 txtdes = mkstemp(tmptxtfile); 05949 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05950 if (txtdes < 0) { 05951 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05952 if (!res) 05953 res = ast_waitstream(chan, ""); 05954 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05955 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05956 inprocess_count(vmu->mailbox, vmu->context, -1); 05957 goto leave_vm_out; 05958 } 05959 05960 /* Now play the beep once we have the message number for our next message. */ 05961 if (res >= 0) { 05962 /* Unless we're *really* silent, try to send the beep */ 05963 res = ast_stream_and_wait(chan, "beep", ""); 05964 } 05965 05966 /* Store information in real-time storage */ 05967 if (ast_check_realtime("voicemail_data")) { 05968 snprintf(priority, sizeof(priority), "%d", chan->priority); 05969 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05970 get_date(date, sizeof(date)); 05971 ast_callerid_merge(callerid, sizeof(callerid), 05972 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05973 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05974 "Unknown"); 05975 ast_store_realtime("voicemail_data", 05976 "origmailbox", ext, 05977 "context", chan->context, 05978 "macrocontext", chan->macrocontext, 05979 "exten", chan->exten, 05980 "priority", priority, 05981 "callerchan", chan->name, 05982 "callerid", callerid, 05983 "origdate", date, 05984 "origtime", origtime, 05985 "category", S_OR(category, ""), 05986 "filename", tmptxtfile, 05987 SENTINEL); 05988 } 05989 05990 /* Store information */ 05991 txt = fdopen(txtdes, "w+"); 05992 if (txt) { 05993 get_date(date, sizeof(date)); 05994 ast_callerid_merge(callerid, sizeof(callerid), 05995 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05996 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05997 "Unknown"); 05998 fprintf(txt, 05999 ";\n" 06000 "; Message Information file\n" 06001 ";\n" 06002 "[message]\n" 06003 "origmailbox=%s\n" 06004 "context=%s\n" 06005 "macrocontext=%s\n" 06006 "exten=%s\n" 06007 "rdnis=%s\n" 06008 "priority=%d\n" 06009 "callerchan=%s\n" 06010 "callerid=%s\n" 06011 "origdate=%s\n" 06012 "origtime=%ld\n" 06013 "category=%s\n", 06014 ext, 06015 chan->context, 06016 chan->macrocontext, 06017 chan->exten, 06018 S_COR(chan->redirecting.from.number.valid, 06019 chan->redirecting.from.number.str, "unknown"), 06020 chan->priority, 06021 chan->name, 06022 callerid, 06023 date, (long) time(NULL), 06024 category ? category : ""); 06025 } else { 06026 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 06027 inprocess_count(vmu->mailbox, vmu->context, -1); 06028 if (ast_check_realtime("voicemail_data")) { 06029 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06030 } 06031 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 06032 goto leave_vm_out; 06033 } 06034 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 06035 06036 if (txt) { 06037 fprintf(txt, "flag=%s\n", flag); 06038 if (sound_duration < vmu->minsecs) { 06039 fclose(txt); 06040 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 06041 ast_filedelete(tmptxtfile, NULL); 06042 unlink(tmptxtfile); 06043 if (ast_check_realtime("voicemail_data")) { 06044 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06045 } 06046 inprocess_count(vmu->mailbox, vmu->context, -1); 06047 } else { 06048 fprintf(txt, "duration=%d\n", duration); 06049 fclose(txt); 06050 if (vm_lock_path(dir)) { 06051 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 06052 /* Delete files */ 06053 ast_filedelete(tmptxtfile, NULL); 06054 unlink(tmptxtfile); 06055 inprocess_count(vmu->mailbox, vmu->context, -1); 06056 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06057 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06058 unlink(tmptxtfile); 06059 ast_unlock_path(dir); 06060 inprocess_count(vmu->mailbox, vmu->context, -1); 06061 if (ast_check_realtime("voicemail_data")) { 06062 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06063 } 06064 } else { 06065 #ifndef IMAP_STORAGE 06066 msgnum = last_message_index(vmu, dir) + 1; 06067 #endif 06068 make_file(fn, sizeof(fn), dir, msgnum); 06069 06070 /* assign a variable with the name of the voicemail file */ 06071 #ifndef IMAP_STORAGE 06072 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06073 #else 06074 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06075 #endif 06076 06077 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06078 ast_filerename(tmptxtfile, fn, NULL); 06079 rename(tmptxtfile, txtfile); 06080 inprocess_count(vmu->mailbox, vmu->context, -1); 06081 06082 /* Properly set permissions on voicemail text descriptor file. 06083 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06084 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06085 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06086 06087 ast_unlock_path(dir); 06088 if (ast_check_realtime("voicemail_data")) { 06089 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06090 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06091 } 06092 /* We must store the file first, before copying the message, because 06093 * ODBC storage does the entire copy with SQL. 06094 */ 06095 if (ast_fileexists(fn, NULL, NULL) > 0) { 06096 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06097 } 06098 06099 /* Are there to be more recipients of this message? */ 06100 while (tmpptr) { 06101 struct ast_vm_user recipu, *recip; 06102 char *exten, *cntx; 06103 06104 exten = strsep(&tmpptr, "&"); 06105 cntx = strchr(exten, '@'); 06106 if (cntx) { 06107 *cntx = '\0'; 06108 cntx++; 06109 } 06110 if ((recip = find_user(&recipu, cntx, exten))) { 06111 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06112 free_user(recip); 06113 } 06114 } 06115 #ifndef IMAP_STORAGE 06116 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06117 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06118 char sfn[PATH_MAX]; 06119 char dfn[PATH_MAX]; 06120 int x; 06121 /* It's easier just to try to make it than to check for its existence */ 06122 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06123 x = last_message_index(vmu, urgdir) + 1; 06124 make_file(sfn, sizeof(sfn), dir, msgnum); 06125 make_file(dfn, sizeof(dfn), urgdir, x); 06126 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06127 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06128 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06129 ast_copy_string(fn, dfn, sizeof(fn)); 06130 msgnum = x; 06131 } 06132 #endif 06133 /* Notification needs to happen after the copy, though. */ 06134 if (ast_fileexists(fn, NULL, NULL)) { 06135 #ifdef IMAP_STORAGE 06136 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06137 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06138 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06139 flag); 06140 #else 06141 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06142 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06143 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06144 flag); 06145 #endif 06146 } 06147 06148 /* Disposal needs to happen after the optional move and copy */ 06149 if (ast_fileexists(fn, NULL, NULL)) { 06150 DISPOSE(dir, msgnum); 06151 } 06152 } 06153 } 06154 } else { 06155 inprocess_count(vmu->mailbox, vmu->context, -1); 06156 } 06157 if (res == '0') { 06158 goto transfer; 06159 } else if (res > 0 && res != 't') 06160 res = 0; 06161 06162 if (sound_duration < vmu->minsecs) 06163 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06164 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06165 else 06166 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06167 } else 06168 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06169 leave_vm_out: 06170 free_user(vmu); 06171 06172 #ifdef IMAP_STORAGE 06173 /* expunge message - use UID Expunge if supported on IMAP server*/ 06174 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06175 if (expungeonhangup == 1) { 06176 ast_mutex_lock(&vms->lock); 06177 #ifdef HAVE_IMAP_TK2006 06178 if (LEVELUIDPLUS (vms->mailstream)) { 06179 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06180 } else 06181 #endif 06182 mail_expunge(vms->mailstream); 06183 ast_mutex_unlock(&vms->lock); 06184 } 06185 #endif 06186 06187 ast_free(tmp); 06188 return res; 06189 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11783 of file app_voicemail.c.
References actual_load_config(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_log(), ast_unload_realtime(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, and VOICEMAIL_CONFIG.
Referenced by handle_voicemail_reload(), load_module(), and reload().
11784 { 11785 struct ast_config *cfg, *ucfg; 11786 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11787 int res; 11788 11789 ast_unload_realtime("voicemail"); 11790 ast_unload_realtime("voicemail_data"); 11791 11792 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11793 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11794 return 0; 11795 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11796 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11797 ucfg = NULL; 11798 } 11799 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11800 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11801 ast_config_destroy(ucfg); 11802 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11803 return 0; 11804 } 11805 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11806 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11807 return 0; 11808 } else { 11809 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11810 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11811 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11812 ucfg = NULL; 11813 } 11814 } 11815 11816 res = actual_load_config(reload, cfg, ucfg); 11817 11818 ast_config_destroy(cfg); 11819 ast_config_destroy(ucfg); 11820 11821 return res; 11822 }
static int load_module | ( | void | ) | [static] |
Definition at line 13084 of file app_voicemail.c.
References ao2_container_alloc, app, app2, app3, app4, ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_data_register_multiple, ast_install_vm_functions(), ast_log(), AST_LOG_WARNING, ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, ast_realtime_require_field(), ast_register_application_xml, ast_taskprocessor_get(), AST_TEST_REGISTER, cli_voicemail, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), inboxcount2(), inprocess_cmp_fn(), inprocess_container, inprocess_hash_fn(), load_config(), mailbox_exists_acf, manager_list_voicemail_users(), messagecount(), mwi_subscription_tps, my_umask, RQ_CHAR, RQ_UINTEGER3, sayname(), sayname_app, SENTINEL, vm_box_exists(), vm_data_providers, vm_exec(), vm_execmain(), VM_SPOOL_DIR, vmauthenticate(), and vmsayname_exec().
13085 { 13086 int res; 13087 my_umask = umask(0); 13088 umask(my_umask); 13089 13090 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13091 return AST_MODULE_LOAD_DECLINE; 13092 } 13093 13094 /* compute the location of the voicemail spool directory */ 13095 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13096 13097 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13098 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13099 } 13100 13101 if ((res = load_config(0))) 13102 return res; 13103 13104 res = ast_register_application_xml(app, vm_exec); 13105 res |= ast_register_application_xml(app2, vm_execmain); 13106 res |= ast_register_application_xml(app3, vm_box_exists); 13107 res |= ast_register_application_xml(app4, vmauthenticate); 13108 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13109 res |= ast_custom_function_register(&mailbox_exists_acf); 13110 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13111 #ifdef TEST_FRAMEWORK 13112 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13113 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13114 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13115 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13116 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13117 #endif 13118 13119 if (res) 13120 return res; 13121 13122 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13123 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13124 13125 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13126 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13127 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13128 13129 return res; 13130 }
static int make_dir | ( | char * | dest, | |
int | len, | |||
const char * | context, | |||
const char * | ext, | |||
const char * | folder | |||
) | [static] |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.
dest | The variable to hold the output generated path expression. This buffer should be of size PATH_MAX. | |
len | The length of the path string that was written out. | |
context | ||
ext | ||
folder |
The path is constructed as VM_SPOOL_DIRcontext/ext/folder
Definition at line 1652 of file app_voicemail.c.
References VM_SPOOL_DIR.
Referenced by copy_message(), create_dirpath(), make_email_file(), manager_list_voicemail_users(), notify_new_message(), and prep_email_sub_vars().
01653 { 01654 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01655 }
static void make_email_file | ( | FILE * | p, | |
char * | srcemail, | |||
struct ast_vm_user * | vmu, | |||
int | msgnum, | |||
char * | context, | |||
char * | mailbox, | |||
const char * | fromfolder, | |||
char * | cidnum, | |||
char * | cidname, | |||
char * | attach, | |||
char * | attach2, | |||
char * | format, | |||
int | duration, | |||
int | attach_user_voicemail, | |||
struct ast_channel * | chan, | |||
const char * | category, | |||
int | imap, | |||
const char * | flag | |||
) | [static] |
Creates the email file to be sent to indicate a new voicemail exists for a user.
p | The output file to generate the email contents into. | |
srcemail | The email address to send the email to, presumably the email address for the owner of the mailbox. | |
vmu | The voicemail user who is sending the voicemail. | |
msgnum | The message index in the mailbox folder. | |
context | ||
mailbox | The voicemail box to read the voicemail to be notified in this email. | |
fromfolder | ||
cidnum | The caller ID number. | |
cidname | The caller ID name. | |
attach | the name of the sound file to be attached to the email, if attach_user_voicemail == 1. | |
attach2 | ||
format | The message sound file format. i.e. .wav | |
duration | The time of the message content, in seconds. | |
attach_user_voicemail | if 1, the sound file is attached to the email. | |
chan | ||
category | ||
imap | if == 1, indicates the target folder for the email notification to be sent to will be an IMAP mailstore. This causes additional mailbox headers to be set, which would facilitate searching for the email in the destination IMAP folder. | |
flag | The email body, and base 64 encoded attachement (if any) are stored to the file identified by *p. This method does not actually send the email. That is done by invoking the configure 'mailcmd' and piping this generated file into it, or with the sendemail() function. |
Definition at line 4567 of file app_voicemail.c.
References add_email_attachment(), ast_channel_unref, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_dummy_channel_alloc, ast_free, ast_localtime(), ast_log(), AST_LOG_WARNING, ast_random(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strftime(), ast_strftime_locale(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), charset, check_mime(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, emailbody, emaildateformat, ast_vm_user::emailsubject, emailsubject, ENDL, fromstring, ast_vm_user::fullname, globalflags, ast_vm_user::locale, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, prep_email_sub_vars(), ast_channel::priority, S_OR, strip_control_and_high(), valid_config(), VM_PBXSKIP, and vmu_tm().
Referenced by sendmail().
04568 { 04569 char date[256]; 04570 char host[MAXHOSTNAMELEN] = ""; 04571 char who[256]; 04572 char bound[256]; 04573 char dur[256]; 04574 struct ast_tm tm; 04575 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04576 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04577 char *greeting_attachment; 04578 char filename[256]; 04579 04580 if (!str1 || !str2) { 04581 ast_free(str1); 04582 ast_free(str2); 04583 return; 04584 } 04585 04586 if (cidnum) { 04587 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04588 } 04589 if (cidname) { 04590 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04591 } 04592 gethostname(host, sizeof(host) - 1); 04593 04594 if (strchr(srcemail, '@')) { 04595 ast_copy_string(who, srcemail, sizeof(who)); 04596 } else { 04597 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04598 } 04599 04600 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04601 if (greeting_attachment) { 04602 *greeting_attachment++ = '\0'; 04603 } 04604 04605 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04606 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04607 fprintf(p, "Date: %s" ENDL, date); 04608 04609 /* Set date format for voicemail mail */ 04610 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04611 04612 if (!ast_strlen_zero(fromstring)) { 04613 struct ast_channel *ast; 04614 if ((ast = ast_dummy_channel_alloc())) { 04615 char *ptr; 04616 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04617 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04618 04619 if (check_mime(ast_str_buffer(str1))) { 04620 int first_line = 1; 04621 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04622 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04623 *ptr = '\0'; 04624 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04625 first_line = 0; 04626 /* Substring is smaller, so this will never grow */ 04627 ast_str_set(&str2, 0, "%s", ptr + 1); 04628 } 04629 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04630 } else { 04631 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04632 } 04633 ast = ast_channel_unref(ast); 04634 } else { 04635 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04636 } 04637 } else { 04638 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04639 } 04640 04641 if (check_mime(vmu->fullname)) { 04642 int first_line = 1; 04643 char *ptr; 04644 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04645 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04646 *ptr = '\0'; 04647 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04648 first_line = 0; 04649 /* Substring is smaller, so this will never grow */ 04650 ast_str_set(&str2, 0, "%s", ptr + 1); 04651 } 04652 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04653 } else { 04654 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04655 } 04656 04657 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04658 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04659 struct ast_channel *ast; 04660 if ((ast = ast_dummy_channel_alloc())) { 04661 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04662 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04663 if (check_mime(ast_str_buffer(str1))) { 04664 int first_line = 1; 04665 char *ptr; 04666 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04667 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04668 *ptr = '\0'; 04669 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04670 first_line = 0; 04671 /* Substring is smaller, so this will never grow */ 04672 ast_str_set(&str2, 0, "%s", ptr + 1); 04673 } 04674 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04675 } else { 04676 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04677 } 04678 ast = ast_channel_unref(ast); 04679 } else { 04680 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04681 } 04682 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04683 if (ast_strlen_zero(flag)) { 04684 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04685 } else { 04686 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04687 } 04688 } else { 04689 if (ast_strlen_zero(flag)) { 04690 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04691 } else { 04692 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04693 } 04694 } 04695 04696 fprintf(p, "Message-ID: <Asterisk-%d-%u-%s-%d@%s>" ENDL, msgnum + 1, 04697 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04698 if (imap) { 04699 /* additional information needed for IMAP searching */ 04700 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04701 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04702 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04703 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04704 #ifdef IMAP_STORAGE 04705 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04706 #else 04707 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04708 #endif 04709 /* flag added for Urgent */ 04710 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04711 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04712 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04713 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04714 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04715 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04716 if (!ast_strlen_zero(category)) { 04717 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04718 } else { 04719 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04720 } 04721 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04722 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04723 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04724 } 04725 if (!ast_strlen_zero(cidnum)) { 04726 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04727 } 04728 if (!ast_strlen_zero(cidname)) { 04729 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04730 } 04731 fprintf(p, "MIME-Version: 1.0" ENDL); 04732 if (attach_user_voicemail) { 04733 /* Something unique. */ 04734 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%u", msgnum + 1, mailbox, 04735 (int) getpid(), (unsigned int) ast_random()); 04736 04737 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04738 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04739 fprintf(p, "--%s" ENDL, bound); 04740 } 04741 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04742 if (emailbody || vmu->emailbody) { 04743 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04744 struct ast_channel *ast; 04745 if ((ast = ast_dummy_channel_alloc())) { 04746 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04747 ast_str_substitute_variables(&str1, 0, ast, e_body); 04748 #ifdef IMAP_STORAGE 04749 { 04750 /* Convert body to native line terminators for IMAP backend */ 04751 char *line = ast_str_buffer(str1), *next; 04752 do { 04753 /* Terminate line before outputting it to the file */ 04754 if ((next = strchr(line, '\n'))) { 04755 *next++ = '\0'; 04756 } 04757 fprintf(p, "%s" ENDL, line); 04758 line = next; 04759 } while (!ast_strlen_zero(line)); 04760 } 04761 #else 04762 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04763 #endif 04764 ast = ast_channel_unref(ast); 04765 } else { 04766 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04767 } 04768 } else if (msgnum > -1) { 04769 if (strcmp(vmu->mailbox, mailbox)) { 04770 /* Forwarded type */ 04771 struct ast_config *msg_cfg; 04772 const char *v; 04773 int inttime; 04774 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04775 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04776 /* Retrieve info from VM attribute file */ 04777 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04778 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04779 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04780 strcat(fromfile, ".txt"); 04781 } 04782 if ((msg_cfg = ast_config_load(fromfile, config_flags)) && valid_config(msg_cfg)) { 04783 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04784 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04785 } 04786 04787 /* You might be tempted to do origdate, except that a) it's in the wrong 04788 * format, and b) it's missing for IMAP recordings. */ 04789 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04790 struct timeval tv = { inttime, }; 04791 struct ast_tm tm; 04792 ast_localtime(&tv, &tm, NULL); 04793 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04794 } 04795 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04796 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04797 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04798 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04799 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04800 date, origcallerid, origdate); 04801 ast_config_destroy(msg_cfg); 04802 } else { 04803 goto plain_message; 04804 } 04805 } else { 04806 plain_message: 04807 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04808 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04809 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04810 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04811 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04812 } 04813 } else { 04814 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04815 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04816 } 04817 04818 if (imap || attach_user_voicemail) { 04819 if (!ast_strlen_zero(attach2)) { 04820 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04821 ast_debug(5, "creating second attachment filename %s\n", filename); 04822 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04823 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04824 ast_debug(5, "creating attachment filename %s\n", filename); 04825 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04826 } else { 04827 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04828 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04829 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04830 } 04831 } 04832 ast_free(str1); 04833 ast_free(str2); 04834 }
static int make_file | ( | char * | dest, | |
const int | len, | |||
const char * | dir, | |||
const int | num | |||
) | [static] |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.
dest | The variable to hold the output generated path expression. This buffer should be of size PATH_MAX. | |
len | The length of the path string that was written out. | |
dir | ||
num |
The path is constructed as VM_SPOOL_DIRcontext/ext/folder
Definition at line 1669 of file app_voicemail.c.
Referenced by advanced_options(), close_mailbox(), copy_message(), forward_message(), leave_voicemail(), make_email_file(), notify_new_message(), play_message(), prep_email_sub_vars(), resequence_mailbox(), save_to_folder(), vm_execmain(), and vm_forwardoptions().
01670 { 01671 return snprintf(dest, len, "%s/msg%04d", dir, num); 01672 }
static int manager_list_voicemail_users | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager list voicemail users command.
Definition at line 11614 of file app_voicemail.c.
References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_ack(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::context, count_messages(), ast_vm_user::dialout, ast_vm_user::email, ast_vm_user::exit, ast_vm_user::fullname, inboxcount(), ast_vm_user::language, ast_vm_user::mailbox, mailcmd, make_dir(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::pager, RESULT_SUCCESS, ast_vm_user::saydurationm, serveremail, ast_vm_user::serveremail, ast_vm_user::uniqueid, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_OPERATOR, VM_REVIEW, VM_SAYCID, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by load_module().
11615 { 11616 struct ast_vm_user *vmu = NULL; 11617 const char *id = astman_get_header(m, "ActionID"); 11618 char actionid[128] = ""; 11619 11620 if (!ast_strlen_zero(id)) 11621 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11622 11623 AST_LIST_LOCK(&users); 11624 11625 if (AST_LIST_EMPTY(&users)) { 11626 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11627 AST_LIST_UNLOCK(&users); 11628 return RESULT_SUCCESS; 11629 } 11630 11631 astman_send_ack(s, m, "Voicemail user list will follow"); 11632 11633 AST_LIST_TRAVERSE(&users, vmu, list) { 11634 char dirname[256]; 11635 11636 #ifdef IMAP_STORAGE 11637 int new, old; 11638 inboxcount(vmu->mailbox, &new, &old); 11639 #endif 11640 11641 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11642 astman_append(s, 11643 "%s" 11644 "Event: VoicemailUserEntry\r\n" 11645 "VMContext: %s\r\n" 11646 "VoiceMailbox: %s\r\n" 11647 "Fullname: %s\r\n" 11648 "Email: %s\r\n" 11649 "Pager: %s\r\n" 11650 "ServerEmail: %s\r\n" 11651 "MailCommand: %s\r\n" 11652 "Language: %s\r\n" 11653 "TimeZone: %s\r\n" 11654 "Callback: %s\r\n" 11655 "Dialout: %s\r\n" 11656 "UniqueID: %s\r\n" 11657 "ExitContext: %s\r\n" 11658 "SayDurationMinimum: %d\r\n" 11659 "SayEnvelope: %s\r\n" 11660 "SayCID: %s\r\n" 11661 "AttachMessage: %s\r\n" 11662 "AttachmentFormat: %s\r\n" 11663 "DeleteMessage: %s\r\n" 11664 "VolumeGain: %.2f\r\n" 11665 "CanReview: %s\r\n" 11666 "CallOperator: %s\r\n" 11667 "MaxMessageCount: %d\r\n" 11668 "MaxMessageLength: %d\r\n" 11669 "NewMessageCount: %d\r\n" 11670 #ifdef IMAP_STORAGE 11671 "OldMessageCount: %d\r\n" 11672 "IMAPUser: %s\r\n" 11673 #endif 11674 "\r\n", 11675 actionid, 11676 vmu->context, 11677 vmu->mailbox, 11678 vmu->fullname, 11679 vmu->email, 11680 vmu->pager, 11681 ast_strlen_zero(vmu->serveremail) ? serveremail : vmu->serveremail, 11682 mailcmd, 11683 vmu->language, 11684 vmu->zonetag, 11685 vmu->callback, 11686 vmu->dialout, 11687 vmu->uniqueid, 11688 vmu->exit, 11689 vmu->saydurationm, 11690 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11691 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11692 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11693 vmu->attachfmt, 11694 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11695 vmu->volgain, 11696 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11697 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11698 vmu->maxmsg, 11699 vmu->maxsecs, 11700 #ifdef IMAP_STORAGE 11701 new, old, vmu->imapuser 11702 #else 11703 count_messages(vmu, dirname) 11704 #endif 11705 ); 11706 } 11707 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11708 11709 AST_LIST_UNLOCK(&users); 11710 11711 return RESULT_SUCCESS; 11712 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11435 of file app_voicemail.c.
References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), poll_cond, poll_freq, poll_subscribed_mailboxes(), and poll_thread_run.
Referenced by start_poll_thread().
11436 { 11437 while (poll_thread_run) { 11438 struct timespec ts = { 0, }; 11439 struct timeval wait; 11440 11441 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11442 ts.tv_sec = wait.tv_sec; 11443 ts.tv_nsec = wait.tv_usec * 1000; 11444 11445 ast_mutex_lock(&poll_lock); 11446 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11447 ast_mutex_unlock(&poll_lock); 11448 11449 if (!poll_thread_run) 11450 break; 11451 11452 poll_subscribed_mailboxes(); 11453 } 11454 11455 return NULL; 11456 }
static const char* mbox | ( | struct ast_vm_user * | vmu, | |
int | id | |||
) | [static] |
Definition at line 1730 of file app_voicemail.c.
References ARRAY_LEN, and mailbox_folders.
Referenced by acf_mailbox_exists(), add_peer_mailboxes(), adsi_load_vmail(), build_gateway(), copy_message(), get_folder(), has_voicemail(), notify_new_message(), open_mailbox(), save_to_folder(), vm_box_exists(), and vm_execmain().
01731 { 01732 #ifdef IMAP_STORAGE 01733 if (vmu && id == 0) { 01734 return vmu->imapfolder; 01735 } 01736 #endif 01737 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01738 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 5417 of file app_voicemail.c.
References __has_voicemail().
Referenced by load_module().
05418 { 05419 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05420 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11458 of file app_voicemail.c.
References ast_free.
Referenced by handle_unsubscribe().
11459 { 11460 ast_free(mwi_sub); 11461 }
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11546 of file app_voicemail.c.
References ast_calloc, ast_event_get_ie_str(), ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_SUB, ast_free, ast_log(), ast_strdup, ast_taskprocessor_push(), mwi_sub_task::context, handle_subscribe(), LOG_ERROR, mwi_sub_task::mailbox, mwi_subscription_tps, and mwi_sub_task::uniqueid.
Referenced by start_poll_thread().
11547 { 11548 struct mwi_sub_task *mwist; 11549 11550 if (ast_event_get_type(event) != AST_EVENT_SUB) 11551 return; 11552 11553 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11554 return; 11555 11556 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11557 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11558 return; 11559 } 11560 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11561 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11562 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11563 11564 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11565 ast_free(mwist); 11566 } 11567 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11520 of file app_voicemail.c.
References ast_calloc, ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_UNSUB, ast_free, ast_log(), ast_taskprocessor_push(), handle_unsubscribe(), LOG_ERROR, mwi_subscription_tps, and mwi_sub_task::uniqueid.
Referenced by start_poll_thread().
11521 { 11522 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11523 11524 if (!uniqueid) { 11525 ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); 11526 return; 11527 } 11528 11529 if (ast_event_get_type(event) != AST_EVENT_UNSUB) { 11530 ast_free(uniqueid); 11531 return; 11532 } 11533 11534 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { 11535 ast_free(uniqueid); 11536 return; 11537 } 11538 11539 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11540 *uniqueid = u; 11541 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11542 ast_free(uniqueid); 11543 } 11544 }
static int notify_new_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms, | |||
int | msgnum, | |||
long | duration, | |||
char * | fmt, | |||
char * | cidnum, | |||
char * | cidname, | |||
const char * | flag | |||
) | [static] |
Sends email notification that a user has a new voicemail waiting for them.
chan | ||
vmu | ||
vms | ||
msgnum | ||
duration | ||
fmt | ||
cidnum | The Caller ID phone number value. | |
cidname | The Caller ID name value. | |
flag |
Definition at line 7103 of file app_voicemail.c.
References ast_app_has_voicemail(), ast_app_inboxcount2(), ast_channel_lock, ast_channel_unlock, ast_log(), AST_LOG_WARNING, ast_manager_event, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::attachfmt, ast_vm_user::context, vm_state::curmsg, DELETE, DISPOSE, ast_vm_user::email, EVENT_FLAG_CALL, ast_vm_user::mailbox, make_dir(), make_file(), mbox(), vm_state::newmessages, ast_vm_user::pager, pbx_builtin_getvar_helper(), queue_mwi_event(), RETRIEVE, run_externnotify(), sendmail(), sendpage(), ast_vm_user::serveremail, serveremail, VM_ATTACH, vm_delete(), VM_DELETE, and VM_SPOOL_DIR.
Referenced by copy_message(), and leave_voicemail().
07104 { 07105 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07106 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07107 const char *category; 07108 char *myserveremail = serveremail; 07109 07110 ast_channel_lock(chan); 07111 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07112 category = ast_strdupa(category); 07113 } 07114 ast_channel_unlock(chan); 07115 07116 #ifndef IMAP_STORAGE 07117 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07118 #else 07119 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07120 #endif 07121 make_file(fn, sizeof(fn), todir, msgnum); 07122 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07123 07124 if (!ast_strlen_zero(vmu->attachfmt)) { 07125 if (strstr(fmt, vmu->attachfmt)) 07126 fmt = vmu->attachfmt; 07127 else 07128 ast_log(AST_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); 07129 } 07130 07131 /* Attach only the first format */ 07132 fmt = ast_strdupa(fmt); 07133 stringp = fmt; 07134 strsep(&stringp, "|"); 07135 07136 if (!ast_strlen_zero(vmu->serveremail)) 07137 myserveremail = vmu->serveremail; 07138 07139 if (!ast_strlen_zero(vmu->email)) { 07140 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07141 07142 if (attach_user_voicemail) 07143 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07144 07145 /* XXX possible imap issue, should category be NULL XXX */ 07146 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07147 07148 if (attach_user_voicemail) 07149 DISPOSE(todir, msgnum); 07150 } 07151 07152 if (!ast_strlen_zero(vmu->pager)) { 07153 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07154 } 07155 07156 if (ast_test_flag(vmu, VM_DELETE)) 07157 DELETE(todir, msgnum, fn, vmu); 07158 07159 /* Leave voicemail for someone */ 07160 if (ast_app_has_voicemail(ext_context, NULL)) 07161 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07162 07163 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07164 07165 ast_manager_event(chan, 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); 07166 run_externnotify(vmu->context, vmu->mailbox, flag); 07167 07168 #ifdef IMAP_STORAGE 07169 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07170 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07171 vm_imap_delete(NULL, vms->curmsg, vmu); 07172 vms->newmessages--; /* Fix new message count */ 07173 } 07174 #endif 07175 07176 return 0; 07177 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4287 of file app_voicemail.c.
References BASELINELEN, ENDL, and baseio::linelength.
Referenced by base_encode().
04288 { 04289 if (bio->linelength >= BASELINELEN) { 04290 if (fputs(ENDL, so) == EOF) { 04291 return -1; 04292 } 04293 04294 bio->linelength = 0; 04295 } 04296 04297 if (putc(((unsigned char) c), so) == EOF) { 04298 return -1; 04299 } 04300 04301 bio->linelength++; 04302 04303 return 1; 04304 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7951 of file app_voicemail.c.
References ast_copy_string(), ast_log(), AST_LOG_ERROR, ast_unlock_path(), ast_vm_user::context, count_messages(), create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, last_message_index(), vm_state::lastmsg, LOG_NOTICE, ast_vm_user::maxmsg, mbox(), resequence_mailbox(), vm_state::username, vm_allocate_dh(), vm_lock_path(), and vm_state::vmbox.
Referenced by vm_execmain().
07952 { 07953 int count_msg, last_msg; 07954 07955 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07956 07957 /* Rename the member vmbox HERE so that we don't try to return before 07958 * we know what's going on. 07959 */ 07960 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07961 07962 /* Faster to make the directory than to check if it exists. */ 07963 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07964 07965 /* traverses directory using readdir (or select query for ODBC) */ 07966 count_msg = count_messages(vmu, vms->curdir); 07967 if (count_msg < 0) { 07968 return count_msg; 07969 } else { 07970 vms->lastmsg = count_msg - 1; 07971 } 07972 07973 if (vm_allocate_dh(vms, vmu, count_msg)) { 07974 return -1; 07975 } 07976 07977 /* 07978 The following test is needed in case sequencing gets messed up. 07979 There appears to be more than one way to mess up sequence, so 07980 we will not try to find all of the root causes--just fix it when 07981 detected. 07982 */ 07983 07984 if (vm_lock_path(vms->curdir)) { 07985 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07986 return ERROR_LOCK_PATH; 07987 } 07988 07989 /* for local storage, checks directory for messages up to maxmsg limit */ 07990 last_msg = last_message_index(vmu, vms->curdir); 07991 ast_unlock_path(vms->curdir); 07992 07993 if (last_msg < -1) { 07994 return last_msg; 07995 } else if (vms->lastmsg != last_msg) { 07996 ast_log(LOG_NOTICE, "Resequencing Mailbox: %s, expected %d but found %d message(s) in box with max threshold of %d.\n", vms->curdir, last_msg + 1, vms->lastmsg + 1, vmu->maxmsg); 07997 resequence_mailbox(vmu, vms->curdir, count_msg); 07998 } 07999 08000 return 0; 08001 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7725 of file app_voicemail.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::heard, vm_state::lastmsg, LOG_WARNING, ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, valid_config(), 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(), vm_browse_messages_vi(), vm_browse_messages_zh(), and vm_execmain().
07726 { 07727 int res = 0; 07728 char filename[256], *cid; 07729 const char *origtime, *context, *category, *duration, *flag; 07730 struct ast_config *msg_cfg; 07731 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07732 07733 vms->starting = 0; 07734 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07735 adsi_message(chan, vms); 07736 if (!vms->curmsg) { 07737 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07738 } else if (vms->curmsg == vms->lastmsg) { 07739 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07740 } 07741 07742 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07743 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07744 msg_cfg = ast_config_load(filename, config_flags); 07745 if (!valid_config(msg_cfg)) { 07746 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07747 return 0; 07748 } 07749 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07750 07751 /* Play the word urgent if we are listening to urgent messages */ 07752 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07753 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07754 } 07755 07756 if (!res) { 07757 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07758 /* POLISH syntax */ 07759 if (!strncasecmp(chan->language, "pl", 2)) { 07760 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07761 int ten, one; 07762 char nextmsg[256]; 07763 ten = (vms->curmsg + 1) / 10; 07764 one = (vms->curmsg + 1) % 10; 07765 07766 if (vms->curmsg < 20) { 07767 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07768 res = wait_file2(chan, vms, nextmsg); 07769 } else { 07770 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07771 res = wait_file2(chan, vms, nextmsg); 07772 if (one > 0) { 07773 if (!res) { 07774 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07775 res = wait_file2(chan, vms, nextmsg); 07776 } 07777 } 07778 } 07779 } 07780 if (!res) 07781 res = wait_file2(chan, vms, "vm-message"); 07782 /* HEBREW syntax */ 07783 } else if (!strncasecmp(chan->language, "he", 2)) { 07784 if (!vms->curmsg) { 07785 res = wait_file2(chan, vms, "vm-message"); 07786 res = wait_file2(chan, vms, "vm-first"); 07787 } else if (vms->curmsg == vms->lastmsg) { 07788 res = wait_file2(chan, vms, "vm-message"); 07789 res = wait_file2(chan, vms, "vm-last"); 07790 } else { 07791 res = wait_file2(chan, vms, "vm-message"); 07792 res = wait_file2(chan, vms, "vm-number"); 07793 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07794 } 07795 /* VIETNAMESE syntax */ 07796 } else if (!strncasecmp(chan->language, "vi", 2)) { 07797 if (!vms->curmsg) { 07798 res = wait_file2(chan, vms, "vm-message"); 07799 res = wait_file2(chan, vms, "vm-first"); 07800 } else if (vms->curmsg == vms->lastmsg) { 07801 res = wait_file2(chan, vms, "vm-message"); 07802 res = wait_file2(chan, vms, "vm-last"); 07803 } else { 07804 res = wait_file2(chan, vms, "vm-message"); 07805 res = wait_file2(chan, vms, "vm-number"); 07806 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07807 } 07808 } else { 07809 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07810 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07811 } else { /* DEFAULT syntax */ 07812 res = wait_file2(chan, vms, "vm-message"); 07813 } 07814 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07815 if (!res) { 07816 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07817 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07818 } 07819 } 07820 } 07821 } 07822 07823 if (!valid_config(msg_cfg)) { 07824 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07825 return 0; 07826 } 07827 07828 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07829 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07830 DISPOSE(vms->curdir, vms->curmsg); 07831 ast_config_destroy(msg_cfg); 07832 return 0; 07833 } 07834 07835 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07836 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07837 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07838 07839 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07840 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07841 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07842 if (!res) { 07843 res = play_message_category(chan, category); 07844 } 07845 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07846 res = play_message_datetime(chan, vmu, origtime, filename); 07847 } 07848 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07849 res = play_message_callerid(chan, vms, cid, context, 0); 07850 } 07851 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07852 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07853 } 07854 /* Allow pressing '1' to skip envelope / callerid */ 07855 if (res == '1') { 07856 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07857 res = 0; 07858 } 07859 ast_config_destroy(msg_cfg); 07860 07861 if (!res) { 07862 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07863 #ifdef IMAP_STORAGE 07864 ast_mutex_lock(&vms->lock); 07865 #endif 07866 vms->heard[vms->curmsg] = 1; 07867 #ifdef IMAP_STORAGE 07868 ast_mutex_unlock(&vms->lock); 07869 /*IMAP storage stores any prepended message from a forward 07870 * as a separate file from the rest of the message 07871 */ 07872 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07873 wait_file(chan, vms, vms->introfn); 07874 } 07875 #endif 07876 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07877 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07878 res = 0; 07879 } 07880 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07881 } 07882 DISPOSE(vms->curdir, vms->curmsg); 07883 return res; 07884 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7611 of file app_voicemail.c.
References ast_callerid_parse(), ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_say_digit_str(), ast_stream_and_wait(), ast_strlen_zero(), ast_verb, cidinternalcontexts, MAX_NUM_CID_CONTEXTS, name, VM_SPOOL_DIR, and wait_file2().
Referenced by advanced_options(), and play_message().
07612 { 07613 int res = 0; 07614 int i; 07615 char *callerid, *name; 07616 char prefile[PATH_MAX] = ""; 07617 07618 07619 /* If voicemail cid is not enabled, or we didn't get cid or context from 07620 * the attribute file, leave now. 07621 * 07622 * TODO Still need to change this so that if this function is called by the 07623 * message envelope (and someone is explicitly requesting to hear the CID), 07624 * it does not check to see if CID is enabled in the config file. 07625 */ 07626 if ((cid == NULL)||(context == NULL)) 07627 return res; 07628 07629 /* Strip off caller ID number from name */ 07630 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07631 ast_callerid_parse(cid, &name, &callerid); 07632 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07633 /* Check for internal contexts and only */ 07634 /* say extension when the call didn't come from an internal context in the list */ 07635 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07636 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07637 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07638 break; 07639 } 07640 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07641 if (!res) { 07642 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07643 if (!ast_strlen_zero(prefile)) { 07644 /* See if we can find a recorded name for this person instead of their extension number */ 07645 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07646 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07647 if (!callback) 07648 res = wait_file2(chan, vms, "vm-from"); 07649 res = ast_stream_and_wait(chan, prefile, ""); 07650 } else { 07651 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07652 /* Say "from extension" as one saying to sound smoother */ 07653 if (!callback) 07654 res = wait_file2(chan, vms, "vm-from-extension"); 07655 res = ast_say_digit_str(chan, callerid, "", chan->language); 07656 } 07657 } 07658 } 07659 } else if (!res) { 07660 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07661 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07662 if (!callback) 07663 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07664 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07665 } 07666 } else { 07667 /* Number unknown */ 07668 ast_debug(1, "VM-CID: From an unknown number\n"); 07669 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07670 res = wait_file2(chan, vms, "vm-unknown-caller"); 07671 } 07672 return res; 07673 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7522 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
07523 { 07524 int res = 0; 07525 07526 if (!ast_strlen_zero(category)) 07527 res = ast_play_and_wait(chan, category); 07528 07529 if (res) { 07530 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07531 res = 0; 07532 } 07533 07534 return res; 07535 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7537 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_LOG_WARNING, ast_say_date_with_format, ast_strlen_zero(), ast_tvnow(), pbx_builtin_setvar_helper(), and ast_vm_user::zonetag.
Referenced by advanced_options(), and play_message().
07538 { 07539 int res = 0; 07540 struct vm_zone *the_zone = NULL; 07541 time_t t; 07542 07543 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07544 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07545 return 0; 07546 } 07547 07548 /* Does this user have a timezone specified? */ 07549 if (!ast_strlen_zero(vmu->zonetag)) { 07550 /* Find the zone in the list */ 07551 struct vm_zone *z; 07552 AST_LIST_LOCK(&zones); 07553 AST_LIST_TRAVERSE(&zones, z, list) { 07554 if (!strcmp(z->name, vmu->zonetag)) { 07555 the_zone = z; 07556 break; 07557 } 07558 } 07559 AST_LIST_UNLOCK(&zones); 07560 } 07561 07562 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07563 #if 0 07564 /* Set the DIFF_* variables */ 07565 ast_localtime(&t, &time_now, NULL); 07566 tv_now = ast_tvnow(); 07567 ast_localtime(&tv_now, &time_then, NULL); 07568 07569 /* Day difference */ 07570 if (time_now.tm_year == time_then.tm_year) 07571 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07572 else 07573 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07574 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07575 07576 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07577 #endif 07578 if (the_zone) { 07579 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07580 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07581 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07582 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07583 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07584 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07585 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); 07586 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07587 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07588 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07589 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07590 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07591 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07592 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07593 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); 07594 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07595 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07596 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07597 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07598 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07599 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' A 'digits/day' dB 'digits/year' Y 'digits/at' k 'hours' M 'minutes'", NULL); 07600 } else { 07601 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07602 } 07603 #if 0 07604 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07605 #endif 07606 return res; 07607 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7675 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), say_and_wait(), and wait_file2().
Referenced by play_message().
07676 { 07677 int res = 0; 07678 int durationm; 07679 int durations; 07680 /* Verify that we have a duration for the message */ 07681 if (duration == NULL) 07682 return res; 07683 07684 /* Convert from seconds to minutes */ 07685 durations = atoi(duration); 07686 durationm = (durations / 60); 07687 07688 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07689 07690 if ((!res) && (durationm >= minduration)) { 07691 res = wait_file2(chan, vms, "vm-duration"); 07692 07693 /* POLISH syntax */ 07694 if (!strncasecmp(chan->language, "pl", 2)) { 07695 div_t num = div(durationm, 10); 07696 07697 if (durationm == 1) { 07698 res = ast_play_and_wait(chan, "digits/1z"); 07699 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07700 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07701 if (num.rem == 2) { 07702 if (!num.quot) { 07703 res = ast_play_and_wait(chan, "digits/2-ie"); 07704 } else { 07705 res = say_and_wait(chan, durationm - 2 , chan->language); 07706 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07707 } 07708 } else { 07709 res = say_and_wait(chan, durationm, chan->language); 07710 } 07711 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07712 } else { 07713 res = say_and_wait(chan, durationm, chan->language); 07714 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07715 } 07716 /* DEFAULT syntax */ 07717 } else { 07718 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07719 res = wait_file2(chan, vms, "vm-minutes"); 07720 } 07721 } 07722 return res; 07723 }
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, | |||
int * | sound_duration, | |||
const char * | unlockdir, | |||
signed char | record_gain, | |||
struct vm_state * | vms, | |||
char * | flag | |||
) | [static] |
Definition at line 13397 of file app_voicemail.c.
References acceptdtmf, ast_channel_setoption(), ast_copy_string(), AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), AST_LOG_WARNING, AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, INTRO, ast_vm_user::mailbox, maxsilence, silencethreshold, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.
Referenced by leave_voicemail(), vm_forwardoptions(), vm_newuser(), vm_options(), and vm_tempgreeting().
13400 { 13401 /* Record message & let caller review or re-record it, or set options if applicable */ 13402 int res = 0; 13403 int cmd = 0; 13404 int max_attempts = 3; 13405 int attempts = 0; 13406 int recorded = 0; 13407 int msg_exists = 0; 13408 signed char zero_gain = 0; 13409 char tempfile[PATH_MAX]; 13410 char *acceptdtmf = "#"; 13411 char *canceldtmf = ""; 13412 int canceleddtmf = 0; 13413 13414 /* Note that urgent and private are for flagging messages as such in the future */ 13415 13416 /* barf if no pointer passed to store duration in */ 13417 if (duration == NULL) { 13418 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13419 return -1; 13420 } 13421 13422 if (!outsidecaller) 13423 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13424 else 13425 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13426 13427 cmd = '3'; /* Want to start by recording */ 13428 13429 while ((cmd >= 0) && (cmd != 't')) { 13430 switch (cmd) { 13431 case '1': 13432 if (!msg_exists) { 13433 /* In this case, 1 is to record a message */ 13434 cmd = '3'; 13435 break; 13436 } else { 13437 /* Otherwise 1 is to save the existing message */ 13438 ast_verb(3, "Saving message as is\n"); 13439 if (!outsidecaller) 13440 ast_filerename(tempfile, recordfile, NULL); 13441 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13442 if (!outsidecaller) { 13443 /* Saves to IMAP server only if imapgreeting=yes */ 13444 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13445 DISPOSE(recordfile, -1); 13446 } 13447 cmd = 't'; 13448 return res; 13449 } 13450 case '2': 13451 /* Review */ 13452 ast_verb(3, "Reviewing the message\n"); 13453 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13454 break; 13455 case '3': 13456 msg_exists = 0; 13457 /* Record */ 13458 if (recorded == 1) 13459 ast_verb(3, "Re-recording the message\n"); 13460 else 13461 ast_verb(3, "Recording the message\n"); 13462 13463 if (recorded && outsidecaller) { 13464 cmd = ast_play_and_wait(chan, INTRO); 13465 cmd = ast_play_and_wait(chan, "beep"); 13466 } 13467 recorded = 1; 13468 /* 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 */ 13469 if (record_gain) 13470 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13471 if (ast_test_flag(vmu, VM_OPERATOR)) 13472 canceldtmf = "0"; 13473 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13474 if (strchr(canceldtmf, cmd)) { 13475 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13476 canceleddtmf = 1; 13477 } 13478 if (record_gain) 13479 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13480 if (cmd == -1) { 13481 /* User has hung up, no options to give */ 13482 if (!outsidecaller) { 13483 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13484 ast_filedelete(tempfile, NULL); 13485 } 13486 return cmd; 13487 } 13488 if (cmd == '0') { 13489 break; 13490 } else if (cmd == '*') { 13491 break; 13492 #if 0 13493 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13494 /* Message is too short */ 13495 ast_verb(3, "Message too short\n"); 13496 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13497 cmd = ast_filedelete(tempfile, NULL); 13498 break; 13499 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13500 /* Message is all silence */ 13501 ast_verb(3, "Nothing recorded\n"); 13502 cmd = ast_filedelete(tempfile, NULL); 13503 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13504 if (!cmd) 13505 cmd = ast_play_and_wait(chan, "vm-speakup"); 13506 break; 13507 #endif 13508 } else { 13509 /* If all is well, a message exists */ 13510 msg_exists = 1; 13511 cmd = 0; 13512 } 13513 break; 13514 case '4': 13515 if (outsidecaller) { /* only mark vm messages */ 13516 /* Mark Urgent */ 13517 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13518 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13519 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13520 strcpy(flag, "Urgent"); 13521 } else if (flag) { 13522 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13523 res = ast_play_and_wait(chan, "vm-marked-nonurgent"); 13524 strcpy(flag, ""); 13525 } else { 13526 ast_play_and_wait(chan, "vm-sorry"); 13527 } 13528 cmd = 0; 13529 } else { 13530 cmd = ast_play_and_wait(chan, "vm-sorry"); 13531 } 13532 break; 13533 case '5': 13534 case '6': 13535 case '7': 13536 case '8': 13537 case '9': 13538 case '*': 13539 case '#': 13540 cmd = ast_play_and_wait(chan, "vm-sorry"); 13541 break; 13542 #if 0 13543 /* XXX Commented out for the moment because of the dangers of deleting 13544 a message while recording (can put the message numbers out of sync) */ 13545 case '*': 13546 /* Cancel recording, delete message, offer to take another message*/ 13547 cmd = ast_play_and_wait(chan, "vm-deleted"); 13548 cmd = ast_filedelete(tempfile, NULL); 13549 if (outsidecaller) { 13550 res = vm_exec(chan, NULL); 13551 return res; 13552 } 13553 else 13554 return 1; 13555 #endif 13556 case '0': 13557 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13558 cmd = ast_play_and_wait(chan, "vm-sorry"); 13559 break; 13560 } 13561 if (msg_exists || recorded) { 13562 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13563 if (!cmd) 13564 cmd = ast_waitfordigit(chan, 3000); 13565 if (cmd == '1') { 13566 ast_filerename(tempfile, recordfile, NULL); 13567 ast_play_and_wait(chan, "vm-msgsaved"); 13568 cmd = '0'; 13569 } else if (cmd == '4') { 13570 if (flag) { 13571 ast_play_and_wait(chan, "vm-marked-urgent"); 13572 strcpy(flag, "Urgent"); 13573 } 13574 ast_play_and_wait(chan, "vm-msgsaved"); 13575 cmd = '0'; 13576 } else { 13577 ast_play_and_wait(chan, "vm-deleted"); 13578 DELETE(tempfile, -1, tempfile, vmu); 13579 cmd = '0'; 13580 } 13581 } 13582 return cmd; 13583 default: 13584 /* If the caller is an ouside caller, and the review option is enabled, 13585 allow them to review the message, but let the owner of the box review 13586 their OGM's */ 13587 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13588 return cmd; 13589 if (msg_exists) { 13590 cmd = ast_play_and_wait(chan, "vm-review"); 13591 if (!cmd && outsidecaller) { 13592 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13593 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13594 } else if (flag) { 13595 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13596 } 13597 } 13598 } else { 13599 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13600 if (!cmd) 13601 cmd = ast_waitfordigit(chan, 600); 13602 } 13603 13604 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13605 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13606 if (!cmd) 13607 cmd = ast_waitfordigit(chan, 600); 13608 } 13609 #if 0 13610 if (!cmd) 13611 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13612 #endif 13613 if (!cmd) 13614 cmd = ast_waitfordigit(chan, 6000); 13615 if (!cmd) { 13616 attempts++; 13617 } 13618 if (attempts > max_attempts) { 13619 cmd = 't'; 13620 } 13621 } 13622 } 13623 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13624 /* Hang up or timeout, so delete the recording. */ 13625 ast_filedelete(tempfile, NULL); 13626 } 13627 13628 if (cmd != 't' && outsidecaller) 13629 ast_play_and_wait(chan, "vm-goodbye"); 13630 13631 return cmd; 13632 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11407 of file app_voicemail.c.
References inboxcount2(), queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11408 { 11409 int new = 0, old = 0, urgent = 0; 11410 11411 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11412 11413 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11414 mwi_sub->old_urgent = urgent; 11415 mwi_sub->old_new = new; 11416 mwi_sub->old_old = old; 11417 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11418 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11419 } 11420 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11422 of file app_voicemail.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), and poll_subscribed_mailbox().
Referenced by mb_poll_thread().
11423 { 11424 struct mwi_sub *mwi_sub; 11425 11426 AST_RWLIST_RDLOCK(&mwi_subs); 11427 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11428 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11429 poll_subscribed_mailbox(mwi_sub); 11430 } 11431 } 11432 AST_RWLIST_UNLOCK(&mwi_subs); 11433 }
static void populate_defaults | ( | struct ast_vm_user * | vmu | ) | [static] |
Sets default voicemail system options to a voicemail user.
This applies select global settings to a newly created (dynamic) instance of a voicemail user.
Definition at line 1014 of file app_voicemail.c.
References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, ast_free, ast_vm_user::callback, callcontext, dialcontext, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, exitcontext, globalflags, locale, ast_vm_user::locale, ast_vm_user::maxdeletedmsg, maxdeletedmsg, ast_vm_user::maxmsg, maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, passwordlocation, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, saydurationminfo, vmmaxsecs, vmminsecs, volgain, ast_vm_user::volgain, zonetag, and ast_vm_user::zonetag.
Referenced by actual_load_config(), append_mailbox(), AST_TEST_DEFINE(), and find_user_realtime().
01015 { 01016 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 01017 vmu->passwordlocation = passwordlocation; 01018 if (saydurationminfo) { 01019 vmu->saydurationm = saydurationminfo; 01020 } 01021 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 01022 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 01023 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 01024 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 01025 ast_copy_string(vmu->locale, locale, sizeof(vmu->locale)); 01026 if (vmminsecs) { 01027 vmu->minsecs = vmminsecs; 01028 } 01029 if (vmmaxsecs) { 01030 vmu->maxsecs = vmmaxsecs; 01031 } 01032 if (maxmsg) { 01033 vmu->maxmsg = maxmsg; 01034 } 01035 if (maxdeletedmsg) { 01036 vmu->maxdeletedmsg = maxdeletedmsg; 01037 } 01038 vmu->volgain = volgain; 01039 ast_free(vmu->emailsubject); 01040 vmu->emailsubject = NULL; 01041 ast_free(vmu->emailbody); 01042 vmu->emailbody = NULL; 01043 #ifdef IMAP_STORAGE 01044 ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder)); 01045 #endif 01046 }
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, | |||
const char * | category, | |||
const char * | flag | |||
) | [static] |
Definition at line 4375 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_strftime_locale(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, emaildateformat, ast_vm_user::fullname, ast_vm_user::locale, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, pbx_builtin_setvar_helper(), S_OR, and valid_config().
Referenced by make_email_file(), and sendpage().
04376 { 04377 char callerid[256]; 04378 char num[12]; 04379 char fromdir[256], fromfile[256]; 04380 struct ast_config *msg_cfg; 04381 const char *origcallerid, *origtime; 04382 char origcidname[80], origcidnum[80], origdate[80]; 04383 int inttime; 04384 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04385 04386 /* Prepare variables for substitution in email body and subject */ 04387 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04388 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04389 snprintf(num, sizeof(num), "%d", msgnum); 04390 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04391 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04392 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04393 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04394 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04395 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04396 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04397 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04398 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04399 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04400 04401 /* Retrieve info from VM attribute file */ 04402 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04403 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04404 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04405 strcat(fromfile, ".txt"); 04406 } 04407 if (!(msg_cfg = ast_config_load(fromfile, config_flags)) || !(valid_config(msg_cfg))) { 04408 if (option_debug > 0) { 04409 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04410 } 04411 return; 04412 } 04413 04414 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04415 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04416 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04417 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04418 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04419 } 04420 04421 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04422 struct timeval tv = { inttime, }; 04423 struct ast_tm tm; 04424 ast_localtime(&tv, &tm, NULL); 04425 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04426 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04427 } 04428 ast_config_destroy(msg_cfg); 04429 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 7066 of file app_voicemail.c.
References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_strdupa, and ast_strlen_zero().
Referenced by append_mailbox(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
07067 { 07068 struct ast_event *event; 07069 char *mailbox, *context; 07070 07071 /* Strip off @default */ 07072 context = mailbox = ast_strdupa(box); 07073 strsep(&context, "@"); 07074 if (ast_strlen_zero(context)) 07075 context = "default"; 07076 07077 if (!(event = ast_event_new(AST_EVENT_MWI, 07078 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 07079 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 07080 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 07081 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 07082 AST_EVENT_IE_END))) { 07083 return; 07084 } 07085 07086 ast_event_queue_and_cache(event); 07087 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12513 of file app_voicemail.c.
References ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), LOG_NOTICE, and valid_config().
Referenced by actual_load_config(), and append_mailbox().
12513 { 12514 struct ast_config *pwconf; 12515 struct ast_flags config_flags = { 0 }; 12516 12517 pwconf = ast_config_load(secretfn, config_flags); 12518 if (valid_config(pwconf)) { 12519 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12520 if (val) { 12521 ast_copy_string(password, val, passwordlen); 12522 ast_config_destroy(pwconf); 12523 return; 12524 } 12525 ast_config_destroy(pwconf); 12526 } 12527 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12528 }
static int reload | ( | void | ) | [static] |
Definition at line 13044 of file app_voicemail.c.
References load_config().
13045 { 13046 return load_config(1); 13047 }
static void rename_file | ( | char * | sfn, | |
char * | dfn | |||
) | [static] |
Renames a message in a mailbox folder.
sfn | The path to the mailbox information and data file to be renamed. | |
dfn | The path for where the message data and information files will be renamed to. |
This method is used by the RENAME macro when mailboxes are stored on the filesystem. (not ODBC and not IMAP).
Definition at line 4045 of file app_voicemail.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
04046 { 04047 char stxt[PATH_MAX]; 04048 char dtxt[PATH_MAX]; 04049 ast_filerename(sfn, dfn, NULL); 04050 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 04051 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 04052 if (ast_check_realtime("voicemail_data")) { 04053 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 04054 } 04055 rename(stxt, dtxt); 04056 }
static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6192 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().
06193 { 06194 /* we know the actual number of messages, so stop process when number is hit */ 06195 06196 int x, dest; 06197 char sfn[PATH_MAX]; 06198 char dfn[PATH_MAX]; 06199 06200 if (vm_lock_path(dir)) { 06201 return ERROR_LOCK_PATH; 06202 } 06203 06204 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06205 make_file(sfn, sizeof(sfn), dir, x); 06206 if (EXISTS(dir, x, sfn, NULL)) { 06207 06208 if (x != dest) { 06209 make_file(dfn, sizeof(dfn), dir, dest); 06210 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06211 } 06212 06213 dest++; 06214 } 06215 } 06216 ast_unlock_path(dir); 06217 06218 return dest; 06219 }
static int reset_user_pw | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | newpass | |||
) | [static] |
Resets a user password to a specified password.
context | ||
mailbox | ||
newpass | This does the actual change password work, called by the vm_change_password() function. |
Definition at line 1484 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::mailbox, and ast_vm_user::password.
Referenced by vm_change_password(), and vm_change_password_shell().
01485 { 01486 /* This function could be made to generate one from a database, too */ 01487 struct ast_vm_user *cur; 01488 int res = -1; 01489 AST_LIST_LOCK(&users); 01490 AST_LIST_TRAVERSE(&users, cur, list) { 01491 if ((!context || !strcasecmp(context, cur->context)) && 01492 (!strcasecmp(mailbox, cur->mailbox))) 01493 break; 01494 } 01495 if (cur) { 01496 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01497 res = 0; 01498 } 01499 AST_LIST_UNLOCK(&users); 01500 return res; 01501 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 5560 of file app_voicemail.c.
References ast_app_has_voicemail(), ast_copy_string(), ast_debug, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, 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, externnotify, ast_smdi_mwi_message::fwd_st, inboxcount2(), S_OR, smdi_iface, and SMDI_MWI_WAIT_TIMEOUT.
Referenced by forward_message(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
05561 { 05562 char arguments[255]; 05563 char ext_context[256] = ""; 05564 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05565 struct ast_smdi_mwi_message *mwi_msg; 05566 05567 if (!ast_strlen_zero(context)) 05568 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05569 else 05570 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05571 05572 if (smdi_iface) { 05573 if (ast_app_has_voicemail(ext_context, NULL)) 05574 ast_smdi_mwi_set(smdi_iface, extension); 05575 else 05576 ast_smdi_mwi_unset(smdi_iface, extension); 05577 05578 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05579 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05580 if (!strncmp(mwi_msg->cause, "INV", 3)) 05581 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05582 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05583 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05584 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05585 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05586 } else { 05587 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05588 } 05589 } 05590 05591 if (!ast_strlen_zero(externnotify)) { 05592 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05593 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05594 } else { 05595 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", 05596 externnotify, S_OR(context, "\"\""), 05597 extension, newvoicemails, 05598 oldvoicemails, urgentvoicemails); 05599 ast_debug(1, "Executing %s\n", arguments); 05600 ast_safe_system(arguments); 05601 } 05602 } 05603 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6229 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_NOTICE, ast_mutex_lock, ast_mutex_unlock, ast_unlock_path(), ast_vm_user::context, COPY, create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, EXISTS, last_message_index(), ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, mbox(), NEW_FOLDER, OLD_FOLDER, RENAME, vm_state::username, and vm_lock_path().
Referenced by close_mailbox(), and vm_execmain().
06230 { 06231 #ifdef IMAP_STORAGE 06232 /* we must use mbox(x) folder names, and copy the message there */ 06233 /* simple. huh? */ 06234 char sequence[10]; 06235 char mailbox[256]; 06236 int res; 06237 06238 /* get the real IMAP message number for this message */ 06239 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06240 06241 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06242 ast_mutex_lock(&vms->lock); 06243 /* if save to Old folder, put in INBOX as read */ 06244 if (box == OLD_FOLDER) { 06245 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06246 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06247 } else if (box == NEW_FOLDER) { 06248 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06249 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06250 } 06251 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06252 ast_mutex_unlock(&vms->lock); 06253 return 0; 06254 } 06255 /* Create the folder if it don't exist */ 06256 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06257 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06258 if (mail_create(vms->mailstream, mailbox) == NIL) 06259 ast_debug(5, "Folder exists.\n"); 06260 else 06261 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06262 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06263 ast_mutex_unlock(&vms->lock); 06264 return res; 06265 #else 06266 char *dir = vms->curdir; 06267 char *username = vms->username; 06268 char *context = vmu->context; 06269 char sfn[PATH_MAX]; 06270 char dfn[PATH_MAX]; 06271 char ddir[PATH_MAX]; 06272 const char *dbox = mbox(vmu, box); 06273 int x, i; 06274 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06275 06276 if (vm_lock_path(ddir)) 06277 return ERROR_LOCK_PATH; 06278 06279 x = last_message_index(vmu, ddir) + 1; 06280 06281 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06282 x--; 06283 for (i = 1; i <= x; i++) { 06284 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06285 make_file(sfn, sizeof(sfn), ddir, i); 06286 make_file(dfn, sizeof(dfn), ddir, i - 1); 06287 if (EXISTS(ddir, i, sfn, NULL)) { 06288 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06289 } else 06290 break; 06291 } 06292 } else { 06293 if (x >= vmu->maxmsg) { 06294 ast_unlock_path(ddir); 06295 return -1; 06296 } 06297 } 06298 make_file(sfn, sizeof(sfn), dir, msg); 06299 make_file(dfn, sizeof(dfn), ddir, x); 06300 if (strcmp(sfn, dfn)) { 06301 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06302 } 06303 ast_unlock_path(ddir); 06304 #endif 06305 return 0; 06306 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6222 of file app_voicemail.c.
References AST_DIGIT_ANY, and ast_say_number().
Referenced by play_message_duration(), vm_execmain(), vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_it(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_se(), vm_intro_vi(), and vm_intro_zh().
06223 { 06224 int d; 06225 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06226 return d; 06227 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12499 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, RETRIEVE, and VM_SPOOL_DIR.
Referenced by load_module(), and vmsayname_exec().
12500 { 12501 int res = -1; 12502 char dir[PATH_MAX]; 12503 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12504 ast_debug(2, "About to try retrieving name file %s\n", dir); 12505 RETRIEVE(dir, -1, mailbox, context); 12506 if (ast_fileexists(dir, NULL, NULL)) { 12507 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12508 } 12509 DISPOSE(dir, -1); 12510 return res; 12511 }
static int sendmail | ( | char * | srcemail, | |
struct ast_vm_user * | vmu, | |||
int | msgnum, | |||
char * | context, | |||
char * | mailbox, | |||
const char * | fromfolder, | |||
char * | cidnum, | |||
char * | cidname, | |||
char * | attach, | |||
char * | attach2, | |||
char * | format, | |||
int | duration, | |||
int | attach_user_voicemail, | |||
struct ast_channel * | chan, | |||
const char * | category, | |||
const char * | flag | |||
) | [static] |
Definition at line 4890 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_WARNING, ast_safe_system(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::email, globalflags, ast_vm_user::mailbox, mailcmd, make_email_file(), VM_ATTACH, and vm_mkftemp().
Referenced by forward_message(), and notify_new_message().
04891 { 04892 FILE *p = NULL; 04893 char tmp[80] = "/tmp/astmail-XXXXXX"; 04894 char tmp2[256]; 04895 char *stringp; 04896 04897 if (vmu && ast_strlen_zero(vmu->email)) { 04898 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04899 return(0); 04900 } 04901 04902 /* Mail only the first format */ 04903 format = ast_strdupa(format); 04904 stringp = format; 04905 strsep(&stringp, "|"); 04906 04907 if (!strcmp(format, "wav49")) 04908 format = "WAV"; 04909 ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %u\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH)); 04910 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04911 command hangs */ 04912 if ((p = vm_mkftemp(tmp)) == NULL) { 04913 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04914 return -1; 04915 } else { 04916 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04917 fclose(p); 04918 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04919 ast_safe_system(tmp2); 04920 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04921 } 04922 return 0; 04923 }
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, | |||
const char * | flag | |||
) | [static] |
Definition at line 4925 of file app_voicemail.c.
References ast_channel_unref, ast_copy_string(), ast_debug, ast_dummy_channel_alloc, ast_free, ast_log(), AST_LOG_WARNING, ast_safe_system(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strftime(), ast_strftime_locale(), ast_strlen_zero(), check_mime(), ENDL, ast_vm_user::fullname, ast_vm_user::locale, mailcmd, MAXHOSTNAMELEN, pagerbody, pagerdateformat, pagerfromstring, pagersubject, prep_email_sub_vars(), S_OR, strip_control_and_high(), vm_mkftemp(), and vmu_tm().
Referenced by notify_new_message().
04926 { 04927 char enc_cidnum[256], enc_cidname[256]; 04928 char date[256]; 04929 char host[MAXHOSTNAMELEN] = ""; 04930 char who[256]; 04931 char dur[PATH_MAX]; 04932 char tmp[80] = "/tmp/astmail-XXXXXX"; 04933 char tmp2[PATH_MAX]; 04934 struct ast_tm tm; 04935 FILE *p; 04936 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04937 04938 if (!str1 || !str2) { 04939 ast_free(str1); 04940 ast_free(str2); 04941 return -1; 04942 } 04943 04944 if (cidnum) { 04945 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04946 } 04947 if (cidname) { 04948 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04949 } 04950 04951 if ((p = vm_mkftemp(tmp)) == NULL) { 04952 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04953 ast_free(str1); 04954 ast_free(str2); 04955 return -1; 04956 } 04957 gethostname(host, sizeof(host)-1); 04958 if (strchr(srcemail, '@')) { 04959 ast_copy_string(who, srcemail, sizeof(who)); 04960 } else { 04961 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04962 } 04963 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04964 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04965 fprintf(p, "Date: %s\n", date); 04966 04967 /* Reformat for custom pager format */ 04968 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04969 04970 if (!ast_strlen_zero(pagerfromstring)) { 04971 struct ast_channel *ast; 04972 if ((ast = ast_dummy_channel_alloc())) { 04973 char *ptr; 04974 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04975 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04976 04977 if (check_mime(ast_str_buffer(str1))) { 04978 int first_line = 1; 04979 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04980 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04981 *ptr = '\0'; 04982 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04983 first_line = 0; 04984 /* Substring is smaller, so this will never grow */ 04985 ast_str_set(&str2, 0, "%s", ptr + 1); 04986 } 04987 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04988 } else { 04989 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04990 } 04991 ast = ast_channel_unref(ast); 04992 } else { 04993 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04994 } 04995 } else { 04996 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04997 } 04998 04999 if (check_mime(vmu->fullname)) { 05000 int first_line = 1; 05001 char *ptr; 05002 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 05003 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 05004 *ptr = '\0'; 05005 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 05006 first_line = 0; 05007 /* Substring is smaller, so this will never grow */ 05008 ast_str_set(&str2, 0, "%s", ptr + 1); 05009 } 05010 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 05011 } else { 05012 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 05013 } 05014 05015 if (!ast_strlen_zero(pagersubject)) { 05016 struct ast_channel *ast; 05017 if ((ast = ast_dummy_channel_alloc())) { 05018 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05019 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 05020 if (check_mime(ast_str_buffer(str1))) { 05021 int first_line = 1; 05022 char *ptr; 05023 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 05024 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 05025 *ptr = '\0'; 05026 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 05027 first_line = 0; 05028 /* Substring is smaller, so this will never grow */ 05029 ast_str_set(&str2, 0, "%s", ptr + 1); 05030 } 05031 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 05032 } else { 05033 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 05034 } 05035 ast = ast_channel_unref(ast); 05036 } else { 05037 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05038 } 05039 } else { 05040 if (ast_strlen_zero(flag)) { 05041 fprintf(p, "Subject: New VM\n\n"); 05042 } else { 05043 fprintf(p, "Subject: New %s VM\n\n", flag); 05044 } 05045 } 05046 05047 if (pagerbody) { 05048 struct ast_channel *ast; 05049 if ((ast = ast_dummy_channel_alloc())) { 05050 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05051 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 05052 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 05053 ast = ast_channel_unref(ast); 05054 } else { 05055 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05056 } 05057 } else { 05058 fprintf(p, "New %s long %s msg in box %s\n" 05059 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 05060 } 05061 05062 fclose(p); 05063 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 05064 ast_safe_system(tmp2); 05065 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 05066 ast_free(str1); 05067 ast_free(str2); 05068 return 0; 05069 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 11064 of file app_voicemail.c.
References ast_category_browse(), ast_cli(), ast_config_destroy(), ast_load_realtime_multientry(), ast_variable_browse(), CLI_FAILURE, CLI_SUCCESS, ast_variable::name, ast_variable::next, SENTINEL, and ast_variable::value.
Referenced by handle_voicemail_show_users().
11065 { 11066 struct ast_config *cfg; 11067 const char *cat = NULL; 11068 11069 if (!(cfg = ast_load_realtime_multientry("voicemail", 11070 "context", context, SENTINEL))) { 11071 return CLI_FAILURE; 11072 } 11073 11074 ast_cli(fd, 11075 "\n" 11076 "=============================================================\n" 11077 "=== Configured Voicemail Users ==============================\n" 11078 "=============================================================\n" 11079 "===\n"); 11080 11081 while ((cat = ast_category_browse(cfg, cat))) { 11082 struct ast_variable *var = NULL; 11083 ast_cli(fd, 11084 "=== Mailbox ...\n" 11085 "===\n"); 11086 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11087 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11088 ast_cli(fd, 11089 "===\n" 11090 "=== ---------------------------------------------------------\n" 11091 "===\n"); 11092 } 11093 11094 ast_cli(fd, 11095 "=============================================================\n" 11096 "\n"); 11097 11098 ast_config_destroy(cfg); 11099 11100 return CLI_SUCCESS; 11101 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11569 of file app_voicemail.c.
References AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_report_subs(), AST_EVENT_SUB, ast_event_subscribe(), AST_EVENT_UNSUB, ast_log(), ast_pthread_create, LOG_ERROR, mb_poll_thread(), mwi_sub_event_cb(), mwi_sub_sub, mwi_unsub_event_cb(), mwi_unsub_sub, poll_thread, and poll_thread_run.
Referenced by actual_load_config().
11570 { 11571 int errcode; 11572 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11573 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11574 AST_EVENT_IE_END); 11575 11576 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11577 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11578 AST_EVENT_IE_END); 11579 11580 if (mwi_sub_sub) 11581 ast_event_report_subs(mwi_sub_sub); 11582 11583 poll_thread_run = 1; 11584 11585 if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) { 11586 ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode)); 11587 } 11588 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11590 of file app_voicemail.c.
References ast_cond_signal, ast_event_unsubscribe(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, mwi_sub_sub, mwi_unsub_sub, poll_cond, poll_thread, and poll_thread_run.
Referenced by actual_load_config(), and unload_module().
11591 { 11592 poll_thread_run = 0; 11593 11594 if (mwi_sub_sub) { 11595 ast_event_unsubscribe(mwi_sub_sub); 11596 mwi_sub_sub = NULL; 11597 } 11598 11599 if (mwi_unsub_sub) { 11600 ast_event_unsubscribe(mwi_unsub_sub); 11601 mwi_unsub_sub = NULL; 11602 } 11603 11604 ast_mutex_lock(&poll_lock); 11605 ast_cond_signal(&poll_cond); 11606 ast_mutex_unlock(&poll_lock); 11607 11608 pthread_join(poll_thread, NULL); 11609 11610 poll_thread = AST_PTHREADT_NULL; 11611 }
static char* strip_control_and_high | ( | const char * | input, | |
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Strips control and non 7-bit clean characters from input string.
Definition at line 984 of file app_voicemail.c.
Referenced by make_email_file(), and sendpage().
static const char * substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 11736 of file app_voicemail.c.
References ast_log(), AST_LOG_NOTICE, ast_str_append(), ast_str_buffer(), ast_str_reset(), and ast_str_thread_get().
Referenced by actual_load_config(), apply_option(), and apply_options_full().
11737 { 11738 char *current; 11739 11740 /* Add 16 for fudge factor */ 11741 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11742 11743 ast_str_reset(str); 11744 11745 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11746 for (current = (char *) value; *current; current++) { 11747 if (*current == '\\') { 11748 current++; 11749 if (!*current) { 11750 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11751 break; 11752 } 11753 switch (*current) { 11754 case '\\': 11755 ast_str_append(&str, 0, "\\"); 11756 break; 11757 case 'r': 11758 ast_str_append(&str, 0, "\r"); 11759 break; 11760 case 'n': 11761 #ifdef IMAP_STORAGE 11762 if (!str->used || str->str[str->used - 1] != '\r') { 11763 ast_str_append(&str, 0, "\r"); 11764 } 11765 #endif 11766 ast_str_append(&str, 0, "\n"); 11767 break; 11768 case 't': 11769 ast_str_append(&str, 0, "\t"); 11770 break; 11771 default: 11772 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11773 break; 11774 } 11775 } else { 11776 ast_str_append(&str, 0, "%c", *current); 11777 } 11778 } 11779 11780 return ast_str_buffer(str); 11781 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13049 of file app_voicemail.c.
References ao2_ref, app, app2, app3, app4, ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_data_unregister, ast_manager_unregister(), AST_PTHREADT_NULL, ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_uninstall_vm_functions(), ast_unload_realtime(), ast_unregister_application(), cli_voicemail, free_vm_users(), free_vm_zones(), inprocess_container, mailbox_exists_acf, mwi_subscription_tps, poll_thread, sayname_app, and stop_poll_thread().
13050 { 13051 int res; 13052 13053 res = ast_unregister_application(app); 13054 res |= ast_unregister_application(app2); 13055 res |= ast_unregister_application(app3); 13056 res |= ast_unregister_application(app4); 13057 res |= ast_unregister_application(sayname_app); 13058 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13059 res |= ast_manager_unregister("VoicemailUsersList"); 13060 res |= ast_data_unregister(NULL); 13061 #ifdef TEST_FRAMEWORK 13062 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13063 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13064 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13065 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13066 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13067 #endif 13068 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13069 ast_uninstall_vm_functions(); 13070 ao2_ref(inprocess_container, -1); 13071 13072 if (poll_thread != AST_PTHREADT_NULL) 13073 stop_poll_thread(); 13074 13075 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13076 ast_unload_realtime("voicemail"); 13077 ast_unload_realtime("voicemail_data"); 13078 13079 free_vm_users(); 13080 free_vm_zones(); 13081 return res; 13082 }
static int valid_config | ( | const struct ast_config * | cfg | ) | [inline, static] |
Check if configuration file is valid.
Definition at line 1506 of file app_voicemail.c.
References CONFIG_STATUS_FILEINVALID.
Referenced by advanced_options(), make_email_file(), play_message(), prep_email_sub_vars(), read_password_from_file(), vm_change_password(), and vm_forwardoptions().
01507 { 01508 return cfg && cfg != CONFIG_STATUS_FILEINVALID; 01509 }
static int vm_allocate_dh | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | count_msg | |||
) | [static] |
Definition at line 1767 of file app_voicemail.c.
References ast_calloc, ast_free, vm_state::deleted, vm_state::dh_arraysize, vm_state::heard, and ast_vm_user::maxmsg.
Referenced by open_mailbox().
01767 { 01768 01769 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01770 01771 /* remove old allocation */ 01772 if (vms->deleted) { 01773 ast_free(vms->deleted); 01774 vms->deleted = NULL; 01775 } 01776 if (vms->heard) { 01777 ast_free(vms->heard); 01778 vms->heard = NULL; 01779 } 01780 vms->dh_arraysize = 0; 01781 01782 if (arraysize > 0) { 01783 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01784 return -1; 01785 } 01786 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01787 ast_free(vms->deleted); 01788 vms->deleted = NULL; 01789 return -1; 01790 } 01791 vms->dh_arraysize = arraysize; 01792 } 01793 01794 return 0; 01795 }
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 | max_logins, | |||
int | silent | |||
) | [static] |
Definition at line 9744 of file app_voicemail.c.
References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_verb, ast_waitstream(), ast_channel::caller, ast_channel::context, find_user(), ast_party_caller::id, ast_party_id::number, ast_vm_user::password, S_COR, ast_party_number::str, ast_party_number::valid, and vm_password.
Referenced by vm_execmain(), and vmauthenticate().
09747 { 09748 int useadsi = 0, valid = 0, logretries = 0; 09749 char password[AST_MAX_EXTENSION]="", *passptr; 09750 struct ast_vm_user vmus, *vmu = NULL; 09751 09752 /* If ADSI is supported, setup login screen */ 09753 adsi_begin(chan, &useadsi); 09754 if (!skipuser && useadsi) 09755 adsi_login(chan); 09756 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09757 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09758 return -1; 09759 } 09760 09761 /* Authenticate them and get their mailbox/password */ 09762 09763 while (!valid && (logretries < max_logins)) { 09764 /* Prompt for, and read in the username */ 09765 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09766 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09767 return -1; 09768 } 09769 if (ast_strlen_zero(mailbox)) { 09770 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09771 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09772 } else { 09773 ast_verb(3, "Username not entered\n"); 09774 return -1; 09775 } 09776 } else if (mailbox[0] == '*') { 09777 /* user entered '*' */ 09778 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09779 if (ast_exists_extension(chan, chan->context, "a", 1, 09780 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09781 return -1; 09782 } 09783 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09784 mailbox[0] = '\0'; 09785 } 09786 09787 if (useadsi) 09788 adsi_password(chan); 09789 09790 if (!ast_strlen_zero(prefix)) { 09791 char fullusername[80] = ""; 09792 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09793 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09794 ast_copy_string(mailbox, fullusername, mailbox_size); 09795 } 09796 09797 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09798 vmu = find_user(&vmus, context, mailbox); 09799 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09800 /* saved password is blank, so don't bother asking */ 09801 password[0] = '\0'; 09802 } else { 09803 if (ast_streamfile(chan, vm_password, chan->language)) { 09804 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09805 return -1; 09806 } 09807 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09808 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09809 return -1; 09810 } else if (password[0] == '*') { 09811 /* user entered '*' */ 09812 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09813 if (ast_exists_extension(chan, chan->context, "a", 1, 09814 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09815 mailbox[0] = '*'; 09816 return -1; 09817 } 09818 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09819 mailbox[0] = '\0'; 09820 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09821 vmu = NULL; 09822 } 09823 } 09824 09825 if (vmu) { 09826 passptr = vmu->password; 09827 if (passptr[0] == '-') passptr++; 09828 } 09829 if (vmu && !strcmp(passptr, password)) 09830 valid++; 09831 else { 09832 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09833 if (!ast_strlen_zero(prefix)) 09834 mailbox[0] = '\0'; 09835 } 09836 logretries++; 09837 if (!valid) { 09838 if (skipuser || logretries >= max_logins) { 09839 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09840 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09841 return -1; 09842 } 09843 } else { 09844 if (useadsi) 09845 adsi_login(chan); 09846 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09847 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09848 return -1; 09849 } 09850 } 09851 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09852 return -1; 09853 } 09854 } 09855 if (!valid && (logretries >= max_logins)) { 09856 ast_stopstream(chan); 09857 ast_play_and_wait(chan, "vm-goodbye"); 09858 return -1; 09859 } 09860 if (vmu && !skipuser) { 09861 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09862 } 09863 return 0; 09864 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10959 of file app_voicemail.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), find_user(), mbox(), and pbx_builtin_setvar_helper().
Referenced by load_module().
10960 { 10961 struct ast_vm_user svm; 10962 char *context, *box; 10963 AST_DECLARE_APP_ARGS(args, 10964 AST_APP_ARG(mbox); 10965 AST_APP_ARG(options); 10966 ); 10967 static int dep_warning = 0; 10968 10969 if (ast_strlen_zero(data)) { 10970 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 10971 return -1; 10972 } 10973 10974 if (!dep_warning) { 10975 dep_warning = 1; 10976 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 10977 } 10978 10979 box = ast_strdupa(data); 10980 10981 AST_STANDARD_APP_ARGS(args, box); 10982 10983 if (args.options) { 10984 } 10985 10986 if ((context = strchr(args.mbox, '@'))) { 10987 *context = '\0'; 10988 context++; 10989 } 10990 10991 if (find_user(&svm, context, args.mbox)) { 10992 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 10993 } else 10994 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 10995 10996 return 0; 10997 }
static int vm_browse_messages | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Top level method to invoke the language variant vm_browse_messages_XX function.
chan | The channel for the current user. We read the language property from this. | |
vms | passed into the language-specific vm_browse_messages function. | |
vmu | passed into the language-specific vm_browse_messages function. |
The method to be invoked is determined by the value of language code property in the user's channel. The default (when unable to match) is to use english.
Definition at line 9726 of file app_voicemail.c.
References vm_browse_messages_en(), vm_browse_messages_he(), vm_browse_messages_latin(), vm_browse_messages_vi(), and vm_browse_messages_zh().
Referenced by vm_execmain().
09727 { 09728 if (!strncasecmp(chan->language, "es", 2) || 09729 !strncasecmp(chan->language, "it", 2) || 09730 !strncasecmp(chan->language, "pt", 2) || 09731 !strncasecmp(chan->language, "gr", 2)) { /* SPANISH, ITALIAN, PORTUGUESE or GREEK */ 09732 return vm_browse_messages_latin(chan, vms, vmu); 09733 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09734 return vm_browse_messages_he(chan, vms, vmu); 09735 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09736 return vm_browse_messages_vi(chan, vms, vmu); 09737 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09738 return vm_browse_messages_zh(chan, vms, vmu); 09739 } else { /* Default to English syntax */ 09740 return vm_browse_messages_en(chan, vms, vmu); 09741 } 09742 }
static int vm_browse_messages_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Default English syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9607 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().
09608 { 09609 int cmd = 0; 09610 09611 if (vms->lastmsg > -1) { 09612 cmd = play_message(chan, vmu, vms); 09613 } else { 09614 cmd = ast_play_and_wait(chan, "vm-youhave"); 09615 if (!cmd) 09616 cmd = ast_play_and_wait(chan, "vm-no"); 09617 if (!cmd) { 09618 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09619 cmd = ast_play_and_wait(chan, vms->fn); 09620 } 09621 if (!cmd) 09622 cmd = ast_play_and_wait(chan, "vm-messages"); 09623 } 09624 return cmd; 09625 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9583 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09584 { 09585 int cmd = 0; 09586 09587 if (vms->lastmsg > -1) { 09588 cmd = play_message(chan, vmu, vms); 09589 } else { 09590 if (!strcasecmp(vms->fn, "INBOX")) { 09591 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09592 } else { 09593 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09594 } 09595 } 09596 return cmd; 09597 }
static int vm_browse_messages_latin | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Common LATIN languages syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9636 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().
09637 { 09638 int cmd; 09639 09640 if (vms->lastmsg > -1) { 09641 cmd = play_message(chan, vmu, vms); 09642 } else { 09643 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09644 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09645 if (!cmd) { 09646 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09647 cmd = ast_play_and_wait(chan, vms->fn); 09648 } 09649 if (!cmd) 09650 cmd = ast_play_and_wait(chan, "vm-messages"); 09651 } else { 09652 if (!cmd) 09653 cmd = ast_play_and_wait(chan, "vm-messages"); 09654 if (!cmd) { 09655 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09656 cmd = ast_play_and_wait(chan, vms->fn); 09657 } 09658 } 09659 } 09660 return cmd; 09661 }
static int vm_browse_messages_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Vietnamese syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9699 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().
09700 { 09701 int cmd = 0; 09702 09703 if (vms->lastmsg > -1) { 09704 cmd = play_message(chan, vmu, vms); 09705 } else { 09706 cmd = ast_play_and_wait(chan, "vm-no"); 09707 if (!cmd) { 09708 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09709 cmd = ast_play_and_wait(chan, vms->fn); 09710 } 09711 } 09712 return cmd; 09713 }
static int vm_browse_messages_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Chinese (Taiwan)syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9671 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().
09672 { 09673 int cmd; 09674 09675 if (vms->lastmsg > -1) { 09676 cmd = play_message(chan, vmu, vms); 09677 } else { 09678 cmd = ast_play_and_wait(chan, "vm-you"); 09679 if (!cmd) 09680 cmd = ast_play_and_wait(chan, "vm-haveno"); 09681 if (!cmd) 09682 cmd = ast_play_and_wait(chan, "vm-messages"); 09683 if (!cmd) { 09684 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09685 cmd = ast_play_and_wait(chan, vms->fn); 09686 } 09687 } 09688 return cmd; 09689 }
static void vm_change_password | ( | struct ast_vm_user * | vmu, | |
const char * | newpassword | |||
) | [static] |
The handler for the change password option.
vmu | The voicemail user to work with. | |
newpassword | The new password (that has been gathered from the appropriate prompting). This is called when a new user logs in for the first time and the option to force them to change their password is set. It is also called when the user wants to change their password from menu option '5' on the mailbox options menu. |
Definition at line 1518 of file app_voicemail.c.
References ast_alloca, ast_category_browse(), ast_category_get(), ast_config_destroy(), ast_config_load, ast_config_text_file_save(), ast_copy_string(), ast_debug, ast_free, ast_log(), AST_LOG_WARNING, ast_test_suite_event_notify, ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), ast_verb, change_password_realtime(), CONFIG_FLAG_WITHCOMMENTS, ast_vm_user::context, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::password, ast_vm_user::passwordlocation, reset_user_pw(), valid_config(), value, var, VM_SPOOL_DIR, VOICEMAIL_CONFIG, and write_password_to_file().
Referenced by vm_newuser(), and vm_options().
01519 { 01520 struct ast_config *cfg = NULL; 01521 struct ast_variable *var = NULL; 01522 struct ast_category *cat = NULL; 01523 char *category = NULL, *value = NULL, *new = NULL; 01524 const char *tmp = NULL; 01525 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01526 char secretfn[PATH_MAX] = ""; 01527 int found = 0; 01528 01529 if (!change_password_realtime(vmu, newpassword)) 01530 return; 01531 01532 /* check if we should store the secret in the spool directory next to the messages */ 01533 switch (vmu->passwordlocation) { 01534 case OPT_PWLOC_SPOOLDIR: 01535 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01536 if (write_password_to_file(secretfn, newpassword) == 0) { 01537 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf"); 01538 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01539 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01540 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01541 break; 01542 } else { 01543 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01544 } 01545 /* Fall-through */ 01546 case OPT_PWLOC_VOICEMAILCONF: 01547 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && valid_config(cfg)) { 01548 while ((category = ast_category_browse(cfg, category))) { 01549 if (!strcasecmp(category, vmu->context)) { 01550 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01551 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01552 break; 01553 } 01554 value = strstr(tmp, ","); 01555 if (!value) { 01556 new = ast_alloca(strlen(newpassword)+1); 01557 sprintf(new, "%s", newpassword); 01558 } else { 01559 new = ast_alloca((strlen(value) + strlen(newpassword) + 1)); 01560 sprintf(new, "%s%s", newpassword, value); 01561 } 01562 if (!(cat = ast_category_get(cfg, category))) { 01563 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01564 break; 01565 } 01566 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01567 found = 1; 01568 } 01569 } 01570 /* save the results */ 01571 if (found) { 01572 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf"); 01573 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01574 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01575 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01576 ast_config_destroy(cfg); 01577 break; 01578 } 01579 01580 ast_config_destroy(cfg); 01581 } 01582 /* Fall-through */ 01583 case OPT_PWLOC_USERSCONF: 01584 /* check users.conf and update the password stored for the mailbox */ 01585 /* if no vmsecret entry exists create one. */ 01586 if ((cfg = ast_config_load("users.conf", config_flags)) && valid_config(cfg)) { 01587 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01588 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01589 ast_debug(4, "users.conf: %s\n", category); 01590 if (!strcasecmp(category, vmu->mailbox)) { 01591 if (!ast_variable_retrieve(cfg, category, "vmsecret")) { 01592 ast_debug(3, "looks like we need to make vmsecret!\n"); 01593 var = ast_variable_new("vmsecret", newpassword, ""); 01594 } else { 01595 var = NULL; 01596 } 01597 new = ast_alloca(strlen(newpassword) + 1); 01598 sprintf(new, "%s", newpassword); 01599 if (!(cat = ast_category_get(cfg, category))) { 01600 ast_debug(4, "failed to get category!\n"); 01601 ast_free(var); 01602 break; 01603 } 01604 if (!var) { 01605 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01606 } else { 01607 ast_variable_append(cat, var); 01608 } 01609 found = 1; 01610 break; 01611 } 01612 } 01613 /* save the results and clean things up */ 01614 if (found) { 01615 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf"); 01616 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01617 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01618 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01619 } 01620 01621 ast_config_destroy(cfg); 01622 } 01623 } 01624 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1626 of file app_voicemail.c.
References ast_copy_string(), ast_debug, ast_safe_system(), ast_test_suite_event_notify, ast_vm_user::context, ext_pass_cmd, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().
Referenced by vm_newuser(), and vm_options().
01627 { 01628 char buf[255]; 01629 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01630 ast_debug(1, "External password: %s\n",buf); 01631 if (!ast_safe_system(buf)) { 01632 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external"); 01633 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01634 /* Reset the password in memory, too */ 01635 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01636 } 01637 }
static char* vm_check_password_shell | ( | char * | command, | |
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1181 of file app_voicemail.c.
References AST_APP_ARG, ast_close_fds_above_n(), AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_safe_fork(), ast_strdupa, errno, and LOG_WARNING.
Referenced by check_password().
01182 { 01183 int fds[2], pid = 0; 01184 01185 memset(buf, 0, len); 01186 01187 if (pipe(fds)) { 01188 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 01189 } else { 01190 /* good to go*/ 01191 pid = ast_safe_fork(0); 01192 01193 if (pid < 0) { 01194 /* ok maybe not */ 01195 close(fds[0]); 01196 close(fds[1]); 01197 snprintf(buf, len, "FAILURE: Fork failed"); 01198 } else if (pid) { 01199 /* parent */ 01200 close(fds[1]); 01201 if (read(fds[0], buf, len) < 0) { 01202 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 01203 } 01204 close(fds[0]); 01205 } else { 01206 /* child */ 01207 AST_DECLARE_APP_ARGS(arg, 01208 AST_APP_ARG(v)[20]; 01209 ); 01210 char *mycmd = ast_strdupa(command); 01211 01212 close(fds[0]); 01213 dup2(fds[1], STDOUT_FILENO); 01214 close(fds[1]); 01215 ast_close_fds_above_n(STDOUT_FILENO); 01216 01217 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 01218 01219 execv(arg.v[0], arg.v); 01220 printf("FAILURE: %s", strerror(errno)); 01221 _exit(0); 01222 } 01223 } 01224 return buf; 01225 }
static int vm_delete | ( | char * | file | ) | [static] |
Removes the voicemail sound and information file.
file | The path to the sound file. This will be the the folder and message index, without the extension. |
This is used by the DELETE macro when voicemails are stored on the file system.
Definition at line 4229 of file app_voicemail.c.
References ast_alloca, ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
Referenced by copy_message(), and notify_new_message().
04230 { 04231 char *txt; 04232 int txtsize = 0; 04233 04234 txtsize = (strlen(file) + 5)*sizeof(char); 04235 txt = ast_alloca(txtsize); 04236 /* Sprintf here would safe because we alloca'd exactly the right length, 04237 * but trying to eliminate all sprintf's anyhow 04238 */ 04239 if (ast_check_realtime("voicemail_data")) { 04240 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04241 } 04242 snprintf(txt, txtsize, "%s.txt", file); 04243 unlink(txt); 04244 return ast_filedelete(file, NULL); 04245 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10618 of file app_voicemail.c.
References ast_channel::_state, args, ast_answer(), AST_APP_ARG, ast_app_getdata(), ast_app_parse_options(), ast_copy_flags, AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, ast_play_and_wait(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, leave_vm_options::exitcontext, leave_voicemail(), OPERATOR_EXIT, OPT_ARG_ARRAY_SIZE, OPT_ARG_DTMFEXIT, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), and leave_vm_options::record_gain.
Referenced by load_module(), and play_record_review().
10619 { 10620 int res = 0; 10621 char *tmp; 10622 struct leave_vm_options leave_options; 10623 struct ast_flags flags = { 0 }; 10624 char *opts[OPT_ARG_ARRAY_SIZE]; 10625 AST_DECLARE_APP_ARGS(args, 10626 AST_APP_ARG(argv0); 10627 AST_APP_ARG(argv1); 10628 ); 10629 10630 memset(&leave_options, 0, sizeof(leave_options)); 10631 10632 if (chan->_state != AST_STATE_UP) 10633 ast_answer(chan); 10634 10635 if (!ast_strlen_zero(data)) { 10636 tmp = ast_strdupa(data); 10637 AST_STANDARD_APP_ARGS(args, tmp); 10638 if (args.argc == 2) { 10639 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10640 return -1; 10641 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10642 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10643 int gain; 10644 10645 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10646 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10647 return -1; 10648 } else { 10649 leave_options.record_gain = (signed char) gain; 10650 } 10651 } 10652 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10653 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10654 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10655 } 10656 } 10657 } else { 10658 char temp[256]; 10659 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10660 if (res < 0) 10661 return res; 10662 if (ast_strlen_zero(temp)) 10663 return 0; 10664 args.argv0 = ast_strdupa(temp); 10665 } 10666 10667 res = leave_voicemail(chan, args.argv0, &leave_options); 10668 if (res == 't') { 10669 ast_play_and_wait(chan, "vm-goodbye"); 10670 res = 0; 10671 } 10672 10673 if (res == OPERATOR_EXIT) { 10674 res = 0; 10675 } 10676 10677 if (res == ERROR_LOCK_PATH) { 10678 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10679 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10680 res = 0; 10681 } 10682 10683 return res; 10684 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9866 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(), args, ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_inboxcount2(), ast_app_parse_options(), ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_goto_if_exists(), ast_log(), AST_LOG_WARNING, ast_manager_event, 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_test_suite_assert, ast_test_suite_event_notify, ast_verb, ast_waitfordigit(), ast_vm_user::callback, close_mailbox(), ast_vm_user::context, vm_state::context, ast_channel::context, vm_state::curdir, vm_state::curmsg, vm_state::deleted, dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), vm_state::fn, forward_message(), free_user(), get_folder2(), get_folder_by_name(), globalflags, has_voicemail(), vm_state::heard, language, ast_vm_user::language, vm_state::lastmsg, ast_vm_user::mailbox, make_file(), maxlogins, ast_vm_user::maxmsg, mbox(), NEW_FOLDER, vm_state::newmessages, OLD_FOLDER, vm_state::oldmessages, open_mailbox(), OPERATOR_EXIT, OPT_ARG_ARRAY_SIZE, OPT_ARG_PLAYFOLDER, OPT_ARG_RECORDGAIN, OPT_AUTOPLAY, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, parse(), ast_vm_user::password, play_message(), queue_mwi_event(), vm_state::repeats, run_externnotify(), save_to_folder(), say_and_wait(), vm_state::starting, vm_state::urgentmessages, vm_state::username, vm_authenticate(), vm_browse_messages(), VM_FORCEGREET, VM_FORCENAME, vm_instructions(), vm_intro(), VM_MESSAGEWRAP, vm_newuser(), vm_options(), vm_play_folder_name(), VM_SKIPAFTERCMD, VM_SVMAIL, vm_state::vmbox, and vmfmts.
Referenced by load_module().
09867 { 09868 /* XXX This is, admittedly, some pretty horrendous code. For some 09869 reason it just seemed a lot easier to do with GOTO's. I feel 09870 like I'm back in my GWBASIC days. XXX */ 09871 int res = -1; 09872 int cmd = 0; 09873 int valid = 0; 09874 char prefixstr[80] =""; 09875 char ext_context[256]=""; 09876 int box; 09877 int useadsi = 0; 09878 int skipuser = 0; 09879 struct vm_state vms; 09880 struct ast_vm_user *vmu = NULL, vmus; 09881 char *context = NULL; 09882 int silentexit = 0; 09883 struct ast_flags flags = { 0 }; 09884 signed char record_gain = 0; 09885 int play_auto = 0; 09886 int play_folder = 0; 09887 int in_urgent = 0; 09888 #ifdef IMAP_STORAGE 09889 int deleted = 0; 09890 #endif 09891 09892 /* Add the vm_state to the active list and keep it active */ 09893 memset(&vms, 0, sizeof(vms)); 09894 09895 vms.lastmsg = -1; 09896 09897 memset(&vmus, 0, sizeof(vmus)); 09898 09899 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09900 if (chan->_state != AST_STATE_UP) { 09901 ast_debug(1, "Before ast_answer\n"); 09902 ast_answer(chan); 09903 } 09904 09905 if (!ast_strlen_zero(data)) { 09906 char *opts[OPT_ARG_ARRAY_SIZE]; 09907 char *parse; 09908 AST_DECLARE_APP_ARGS(args, 09909 AST_APP_ARG(argv0); 09910 AST_APP_ARG(argv1); 09911 ); 09912 09913 parse = ast_strdupa(data); 09914 09915 AST_STANDARD_APP_ARGS(args, parse); 09916 09917 if (args.argc == 2) { 09918 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09919 return -1; 09920 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09921 int gain; 09922 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09923 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09924 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09925 return -1; 09926 } else { 09927 record_gain = (signed char) gain; 09928 } 09929 } else { 09930 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09931 } 09932 } 09933 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09934 play_auto = 1; 09935 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09936 /* See if it is a folder name first */ 09937 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09938 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09939 play_folder = -1; 09940 } 09941 } else { 09942 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09943 } 09944 } else { 09945 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09946 } 09947 if (play_folder > 9 || play_folder < 0) { 09948 ast_log(AST_LOG_WARNING, 09949 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09950 opts[OPT_ARG_PLAYFOLDER]); 09951 play_folder = 0; 09952 } 09953 } 09954 } else { 09955 /* old style options parsing */ 09956 while (*(args.argv0)) { 09957 if (*(args.argv0) == 's') 09958 ast_set_flag(&flags, OPT_SILENT); 09959 else if (*(args.argv0) == 'p') 09960 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 09961 else 09962 break; 09963 (args.argv0)++; 09964 } 09965 09966 } 09967 09968 valid = ast_test_flag(&flags, OPT_SILENT); 09969 09970 if ((context = strchr(args.argv0, '@'))) 09971 *context++ = '\0'; 09972 09973 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 09974 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 09975 else 09976 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 09977 09978 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 09979 skipuser++; 09980 else 09981 valid = 0; 09982 } 09983 09984 if (!valid) 09985 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 09986 09987 ast_debug(1, "After vm_authenticate\n"); 09988 09989 if (vms.username[0] == '*') { 09990 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 09991 09992 /* user entered '*' */ 09993 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 09994 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 09995 res = 0; /* prevent hangup */ 09996 goto out; 09997 } 09998 } 09999 10000 if (!res) { 10001 valid = 1; 10002 if (!skipuser) 10003 vmu = &vmus; 10004 } else { 10005 res = 0; 10006 } 10007 10008 /* If ADSI is supported, setup login screen */ 10009 adsi_begin(chan, &useadsi); 10010 10011 ast_test_suite_assert(valid); 10012 if (!valid) { 10013 goto out; 10014 } 10015 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10016 10017 #ifdef IMAP_STORAGE 10018 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10019 pthread_setspecific(ts_vmstate.key, &vms); 10020 10021 vms.interactive = 1; 10022 vms.updated = 1; 10023 if (vmu) 10024 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10025 vmstate_insert(&vms); 10026 init_vm_state(&vms); 10027 #endif 10028 10029 /* Set language from config to override channel language */ 10030 if (!ast_strlen_zero(vmu->language)) 10031 ast_string_field_set(chan, language, vmu->language); 10032 10033 /* Retrieve urgent, old and new message counts */ 10034 ast_debug(1, "Before open_mailbox\n"); 10035 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10036 if (res < 0) 10037 goto out; 10038 vms.oldmessages = vms.lastmsg + 1; 10039 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10040 /* check INBOX */ 10041 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10042 if (res < 0) 10043 goto out; 10044 vms.newmessages = vms.lastmsg + 1; 10045 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10046 /* Start in Urgent */ 10047 in_urgent = 1; 10048 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10049 if (res < 0) 10050 goto out; 10051 vms.urgentmessages = vms.lastmsg + 1; 10052 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10053 10054 /* Select proper mailbox FIRST!! */ 10055 if (play_auto) { 10056 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10057 if (vms.urgentmessages) { 10058 in_urgent = 1; 10059 res = open_mailbox(&vms, vmu, 11); 10060 } else { 10061 in_urgent = 0; 10062 res = open_mailbox(&vms, vmu, play_folder); 10063 } 10064 if (res < 0) 10065 goto out; 10066 10067 /* If there are no new messages, inform the user and hangup */ 10068 if (vms.lastmsg == -1) { 10069 in_urgent = 0; 10070 cmd = vm_browse_messages(chan, &vms, vmu); 10071 res = 0; 10072 goto out; 10073 } 10074 } else { 10075 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10076 /* If we only have old messages start here */ 10077 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10078 in_urgent = 0; 10079 play_folder = 1; 10080 if (res < 0) 10081 goto out; 10082 } else if (!vms.urgentmessages && vms.newmessages) { 10083 /* If we have new messages but none are urgent */ 10084 in_urgent = 0; 10085 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10086 if (res < 0) 10087 goto out; 10088 } 10089 } 10090 10091 if (useadsi) 10092 adsi_status(chan, &vms); 10093 res = 0; 10094 10095 /* Check to see if this is a new user */ 10096 if (!strcasecmp(vmu->mailbox, vmu->password) && 10097 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10098 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10099 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10100 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10101 if ((cmd == 't') || (cmd == '#')) { 10102 /* Timeout */ 10103 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10104 res = 0; 10105 goto out; 10106 } else if (cmd < 0) { 10107 /* Hangup */ 10108 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10109 res = -1; 10110 goto out; 10111 } 10112 } 10113 #ifdef IMAP_STORAGE 10114 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10115 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10116 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10117 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10118 } 10119 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10120 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10121 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10122 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10123 } 10124 #endif 10125 10126 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10127 if (play_auto) { 10128 cmd = '1'; 10129 } else { 10130 cmd = vm_intro(chan, vmu, &vms); 10131 } 10132 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10133 10134 vms.repeats = 0; 10135 vms.starting = 1; 10136 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10137 /* Run main menu */ 10138 switch (cmd) { 10139 case '1': /* First message */ 10140 vms.curmsg = 0; 10141 /* Fall through */ 10142 case '5': /* Play current message */ 10143 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10144 cmd = vm_browse_messages(chan, &vms, vmu); 10145 break; 10146 case '2': /* Change folders */ 10147 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10148 if (useadsi) 10149 adsi_folders(chan, 0, "Change to folder..."); 10150 10151 cmd = get_folder2(chan, "vm-changeto", 0); 10152 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10153 if (cmd == '#') { 10154 cmd = 0; 10155 } else if (cmd > 0) { 10156 cmd = cmd - '0'; 10157 res = close_mailbox(&vms, vmu); 10158 if (res == ERROR_LOCK_PATH) 10159 goto out; 10160 /* If folder is not urgent, set in_urgent to zero! */ 10161 if (cmd != 11) in_urgent = 0; 10162 res = open_mailbox(&vms, vmu, cmd); 10163 if (res < 0) 10164 goto out; 10165 play_folder = cmd; 10166 cmd = 0; 10167 } 10168 if (useadsi) 10169 adsi_status2(chan, &vms); 10170 10171 if (!cmd) { 10172 cmd = vm_play_folder_name(chan, vms.vmbox); 10173 } 10174 10175 vms.starting = 1; 10176 vms.curmsg = 0; 10177 break; 10178 case '3': /* Advanced options */ 10179 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10180 cmd = 0; 10181 vms.repeats = 0; 10182 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10183 switch (cmd) { 10184 case '1': /* Reply */ 10185 if (vms.lastmsg > -1 && !vms.starting) { 10186 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10187 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10188 res = cmd; 10189 goto out; 10190 } 10191 } else { 10192 cmd = ast_play_and_wait(chan, "vm-sorry"); 10193 } 10194 cmd = 't'; 10195 break; 10196 case '2': /* Callback */ 10197 if (!vms.starting) 10198 ast_verb(3, "Callback Requested\n"); 10199 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10200 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10201 if (cmd == 9) { 10202 silentexit = 1; 10203 goto out; 10204 } else if (cmd == ERROR_LOCK_PATH) { 10205 res = cmd; 10206 goto out; 10207 } 10208 } else { 10209 cmd = ast_play_and_wait(chan, "vm-sorry"); 10210 } 10211 cmd = 't'; 10212 break; 10213 case '3': /* Envelope */ 10214 if (vms.lastmsg > -1 && !vms.starting) { 10215 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10216 if (cmd == ERROR_LOCK_PATH) { 10217 res = cmd; 10218 goto out; 10219 } 10220 } else { 10221 cmd = ast_play_and_wait(chan, "vm-sorry"); 10222 } 10223 cmd = 't'; 10224 break; 10225 case '4': /* Dialout */ 10226 if (!ast_strlen_zero(vmu->dialout)) { 10227 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10228 if (cmd == 9) { 10229 silentexit = 1; 10230 goto out; 10231 } 10232 } else { 10233 cmd = ast_play_and_wait(chan, "vm-sorry"); 10234 } 10235 cmd = 't'; 10236 break; 10237 10238 case '5': /* Leave VoiceMail */ 10239 if (ast_test_flag(vmu, VM_SVMAIL)) { 10240 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10241 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10242 res = cmd; 10243 goto out; 10244 } 10245 } else { 10246 cmd = ast_play_and_wait(chan, "vm-sorry"); 10247 } 10248 cmd = 't'; 10249 break; 10250 10251 case '*': /* Return to main menu */ 10252 cmd = 't'; 10253 break; 10254 10255 default: 10256 cmd = 0; 10257 if (!vms.starting) { 10258 cmd = ast_play_and_wait(chan, "vm-toreply"); 10259 } 10260 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10261 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10262 } 10263 if (!cmd && !vms.starting) { 10264 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10265 } 10266 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10267 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10268 } 10269 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10270 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10271 } 10272 if (!cmd) { 10273 cmd = ast_play_and_wait(chan, "vm-starmain"); 10274 } 10275 if (!cmd) { 10276 cmd = ast_waitfordigit(chan, 6000); 10277 } 10278 if (!cmd) { 10279 vms.repeats++; 10280 } 10281 if (vms.repeats > 3) { 10282 cmd = 't'; 10283 } 10284 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10285 } 10286 } 10287 if (cmd == 't') { 10288 cmd = 0; 10289 vms.repeats = 0; 10290 } 10291 break; 10292 case '4': /* Go to the previous message */ 10293 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10294 if (vms.curmsg > 0) { 10295 vms.curmsg--; 10296 cmd = play_message(chan, vmu, &vms); 10297 } else { 10298 /* Check if we were listening to new 10299 messages. If so, go to Urgent messages 10300 instead of saying "no more messages" 10301 */ 10302 if (in_urgent == 0 && vms.urgentmessages > 0) { 10303 /* Check for Urgent messages */ 10304 in_urgent = 1; 10305 res = close_mailbox(&vms, vmu); 10306 if (res == ERROR_LOCK_PATH) 10307 goto out; 10308 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10309 if (res < 0) 10310 goto out; 10311 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10312 vms.curmsg = vms.lastmsg; 10313 if (vms.lastmsg < 0) { 10314 cmd = ast_play_and_wait(chan, "vm-nomore"); 10315 } 10316 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10317 vms.curmsg = vms.lastmsg; 10318 cmd = play_message(chan, vmu, &vms); 10319 } else { 10320 cmd = ast_play_and_wait(chan, "vm-nomore"); 10321 } 10322 } 10323 break; 10324 case '6': /* Go to the next message */ 10325 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10326 if (vms.curmsg < vms.lastmsg) { 10327 vms.curmsg++; 10328 cmd = play_message(chan, vmu, &vms); 10329 } else { 10330 if (in_urgent && vms.newmessages > 0) { 10331 /* Check if we were listening to urgent 10332 * messages. If so, go to regular new messages 10333 * instead of saying "no more messages" 10334 */ 10335 in_urgent = 0; 10336 res = close_mailbox(&vms, vmu); 10337 if (res == ERROR_LOCK_PATH) 10338 goto out; 10339 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10340 if (res < 0) 10341 goto out; 10342 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10343 vms.curmsg = -1; 10344 if (vms.lastmsg < 0) { 10345 cmd = ast_play_and_wait(chan, "vm-nomore"); 10346 } 10347 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10348 vms.curmsg = 0; 10349 cmd = play_message(chan, vmu, &vms); 10350 } else { 10351 cmd = ast_play_and_wait(chan, "vm-nomore"); 10352 } 10353 } 10354 break; 10355 case '7': /* Delete the current message */ 10356 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10357 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10358 if (useadsi) 10359 adsi_delete(chan, &vms); 10360 if (vms.deleted[vms.curmsg]) { 10361 if (play_folder == 0) { 10362 if (in_urgent) { 10363 vms.urgentmessages--; 10364 } else { 10365 vms.newmessages--; 10366 } 10367 } 10368 else if (play_folder == 1) 10369 vms.oldmessages--; 10370 cmd = ast_play_and_wait(chan, "vm-deleted"); 10371 } else { 10372 if (play_folder == 0) { 10373 if (in_urgent) { 10374 vms.urgentmessages++; 10375 } else { 10376 vms.newmessages++; 10377 } 10378 } 10379 else if (play_folder == 1) 10380 vms.oldmessages++; 10381 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10382 } 10383 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10384 if (vms.curmsg < vms.lastmsg) { 10385 vms.curmsg++; 10386 cmd = play_message(chan, vmu, &vms); 10387 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10388 vms.curmsg = 0; 10389 cmd = play_message(chan, vmu, &vms); 10390 } else { 10391 /* Check if we were listening to urgent 10392 messages. If so, go to regular new messages 10393 instead of saying "no more messages" 10394 */ 10395 if (in_urgent == 1) { 10396 /* Check for new messages */ 10397 in_urgent = 0; 10398 res = close_mailbox(&vms, vmu); 10399 if (res == ERROR_LOCK_PATH) 10400 goto out; 10401 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10402 if (res < 0) 10403 goto out; 10404 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10405 vms.curmsg = -1; 10406 if (vms.lastmsg < 0) { 10407 cmd = ast_play_and_wait(chan, "vm-nomore"); 10408 } 10409 } else { 10410 cmd = ast_play_and_wait(chan, "vm-nomore"); 10411 } 10412 } 10413 } 10414 } else /* Delete not valid if we haven't selected a message */ 10415 cmd = 0; 10416 #ifdef IMAP_STORAGE 10417 deleted = 1; 10418 #endif 10419 break; 10420 10421 case '8': /* Forward the current message */ 10422 if (vms.lastmsg > -1) { 10423 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10424 if (cmd == ERROR_LOCK_PATH) { 10425 res = cmd; 10426 goto out; 10427 } 10428 } else { 10429 /* Check if we were listening to urgent 10430 messages. If so, go to regular new messages 10431 instead of saying "no more messages" 10432 */ 10433 if (in_urgent == 1 && vms.newmessages > 0) { 10434 /* Check for new messages */ 10435 in_urgent = 0; 10436 res = close_mailbox(&vms, vmu); 10437 if (res == ERROR_LOCK_PATH) 10438 goto out; 10439 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10440 if (res < 0) 10441 goto out; 10442 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10443 vms.curmsg = -1; 10444 if (vms.lastmsg < 0) { 10445 cmd = ast_play_and_wait(chan, "vm-nomore"); 10446 } 10447 } else { 10448 cmd = ast_play_and_wait(chan, "vm-nomore"); 10449 } 10450 } 10451 break; 10452 case '9': /* Save message to folder */ 10453 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10454 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10455 /* No message selected */ 10456 cmd = 0; 10457 break; 10458 } 10459 if (useadsi) 10460 adsi_folders(chan, 1, "Save to folder..."); 10461 cmd = get_folder2(chan, "vm-savefolder", 1); 10462 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10463 box = 0; /* Shut up compiler */ 10464 if (cmd == '#') { 10465 cmd = 0; 10466 break; 10467 } else if (cmd > 0) { 10468 box = cmd = cmd - '0'; 10469 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10470 if (cmd == ERROR_LOCK_PATH) { 10471 res = cmd; 10472 goto out; 10473 #ifndef IMAP_STORAGE 10474 } else if (!cmd) { 10475 vms.deleted[vms.curmsg] = 1; 10476 #endif 10477 } else { 10478 vms.deleted[vms.curmsg] = 0; 10479 vms.heard[vms.curmsg] = 0; 10480 } 10481 } 10482 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10483 if (useadsi) 10484 adsi_message(chan, &vms); 10485 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10486 if (!cmd) { 10487 cmd = ast_play_and_wait(chan, "vm-message"); 10488 if (!cmd) 10489 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10490 if (!cmd) 10491 cmd = ast_play_and_wait(chan, "vm-savedto"); 10492 if (!cmd) 10493 cmd = vm_play_folder_name(chan, vms.fn); 10494 } else { 10495 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10496 } 10497 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10498 if (vms.curmsg < vms.lastmsg) { 10499 vms.curmsg++; 10500 cmd = play_message(chan, vmu, &vms); 10501 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10502 vms.curmsg = 0; 10503 cmd = play_message(chan, vmu, &vms); 10504 } else { 10505 /* Check if we were listening to urgent 10506 messages. If so, go to regular new messages 10507 instead of saying "no more messages" 10508 */ 10509 if (in_urgent == 1 && vms.newmessages > 0) { 10510 /* Check for new messages */ 10511 in_urgent = 0; 10512 res = close_mailbox(&vms, vmu); 10513 if (res == ERROR_LOCK_PATH) 10514 goto out; 10515 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10516 if (res < 0) 10517 goto out; 10518 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10519 vms.curmsg = -1; 10520 if (vms.lastmsg < 0) { 10521 cmd = ast_play_and_wait(chan, "vm-nomore"); 10522 } 10523 } else { 10524 cmd = ast_play_and_wait(chan, "vm-nomore"); 10525 } 10526 } 10527 } 10528 break; 10529 case '*': /* Help */ 10530 if (!vms.starting) { 10531 cmd = ast_play_and_wait(chan, "vm-onefor"); 10532 if (!strncasecmp(chan->language, "he", 2)) { 10533 cmd = ast_play_and_wait(chan, "vm-for"); 10534 } 10535 if (!cmd) 10536 cmd = vm_play_folder_name(chan, vms.vmbox); 10537 if (!cmd) 10538 cmd = ast_play_and_wait(chan, "vm-opts"); 10539 if (!cmd) 10540 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10541 } else 10542 cmd = 0; 10543 break; 10544 case '0': /* Mailbox options */ 10545 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10546 if (useadsi) 10547 adsi_status(chan, &vms); 10548 break; 10549 default: /* Nothing */ 10550 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10551 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10552 break; 10553 } 10554 } 10555 if ((cmd == 't') || (cmd == '#')) { 10556 /* Timeout */ 10557 res = 0; 10558 } else { 10559 /* Hangup */ 10560 res = -1; 10561 } 10562 10563 out: 10564 if (res > -1) { 10565 ast_stopstream(chan); 10566 adsi_goodbye(chan); 10567 if (valid && res != OPERATOR_EXIT) { 10568 if (silentexit) 10569 res = ast_play_and_wait(chan, "vm-dialout"); 10570 else 10571 res = ast_play_and_wait(chan, "vm-goodbye"); 10572 } 10573 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10574 res = 0; 10575 } 10576 if (useadsi) 10577 ast_adsi_unload_session(chan); 10578 } 10579 if (vmu) 10580 close_mailbox(&vms, vmu); 10581 if (valid) { 10582 int new = 0, old = 0, urgent = 0; 10583 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10584 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10585 /* Urgent flag not passwd to externnotify here */ 10586 run_externnotify(vmu->context, vmu->mailbox, NULL); 10587 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10588 queue_mwi_event(ext_context, urgent, new, old); 10589 } 10590 #ifdef IMAP_STORAGE 10591 /* expunge message - use UID Expunge if supported on IMAP server*/ 10592 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10593 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10594 ast_mutex_lock(&vms.lock); 10595 #ifdef HAVE_IMAP_TK2006 10596 if (LEVELUIDPLUS (vms.mailstream)) { 10597 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10598 } else 10599 #endif 10600 mail_expunge(vms.mailstream); 10601 ast_mutex_unlock(&vms.lock); 10602 } 10603 /* before we delete the state, we should copy pertinent info 10604 * back to the persistent model */ 10605 if (vmu) { 10606 vmstate_delete(&vms); 10607 } 10608 #endif 10609 if (vmu) 10610 free_user(vmu); 10611 10612 #ifdef IMAP_STORAGE 10613 pthread_setspecific(ts_vmstate.key, NULL); 10614 #endif 10615 return res; 10616 }
static int vm_forwardoptions | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | curdir, | |||
int | curmsg, | |||
char * | vm_fmts, | |||
char * | context, | |||
signed char | record_gain, | |||
long * | duration, | |||
struct vm_state * | vms, | |||
char * | flag | |||
) | [static] |
presents the option to prepend to an existing message when forwarding it.
chan | ||
vmu | ||
curdir | ||
curmsg | ||
vm_fmts | ||
context | ||
record_gain | ||
duration | ||
vms | ||
flag |
Presents a prompt for 1 to prepend the current message, 2 to forward the message without prepending, or * to return to the main menu.
This is invoked from forward_message() when performing a forward operation (option 8 from main menu).
Definition at line 6910 of file app_voicemail.c.
References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load, ast_config_text_file_save(), ast_filecopy(), ast_filerename(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_stream_and_wait(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), CONFIG_FLAG_NOCACHE, copy(), INTRO, make_file(), ast_vm_user::maxsecs, maxsilence, play_record_review(), silencethreshold, valid_config(), vm_pls_try_again, and vm_prepend_timeout.
Referenced by forward_message().
06912 { 06913 int cmd = 0; 06914 int retries = 0, prepend_duration = 0, already_recorded = 0; 06915 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06916 char textfile[PATH_MAX]; 06917 struct ast_config *msg_cfg; 06918 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06919 #ifndef IMAP_STORAGE 06920 signed char zero_gain = 0; 06921 #endif 06922 const char *duration_str; 06923 06924 /* Must always populate duration correctly */ 06925 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06926 strcpy(textfile, msgfile); 06927 strcpy(backup, msgfile); 06928 strcpy(backup_textfile, msgfile); 06929 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06930 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06931 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06932 06933 if ((msg_cfg = ast_config_load(textfile, config_flags)) && valid_config(msg_cfg) && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06934 *duration = atoi(duration_str); 06935 } else { 06936 *duration = 0; 06937 } 06938 06939 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06940 if (cmd) 06941 retries = 0; 06942 switch (cmd) { 06943 case '1': 06944 06945 #ifdef IMAP_STORAGE 06946 /* Record new intro file */ 06947 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06948 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06949 ast_play_and_wait(chan, INTRO); 06950 ast_play_and_wait(chan, "beep"); 06951 cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06952 if (cmd == -1) { 06953 break; 06954 } 06955 cmd = 't'; 06956 #else 06957 06958 /* prepend a message to the current message, update the metadata and return */ 06959 06960 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06961 strcpy(textfile, msgfile); 06962 strncat(textfile, ".txt", sizeof(textfile) - 1); 06963 *duration = 0; 06964 06965 /* if we can't read the message metadata, stop now */ 06966 if (!valid_config(msg_cfg)) { 06967 cmd = 0; 06968 break; 06969 } 06970 06971 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06972 #ifndef IMAP_STORAGE 06973 if (already_recorded) { 06974 ast_filecopy(backup, msgfile, NULL); 06975 copy(backup_textfile, textfile); 06976 } 06977 else { 06978 ast_filecopy(msgfile, backup, NULL); 06979 copy(textfile, backup_textfile); 06980 } 06981 #endif 06982 already_recorded = 1; 06983 06984 if (record_gain) 06985 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06986 06987 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 06988 06989 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 06990 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 06991 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 06992 ast_filerename(backup, msgfile, NULL); 06993 } 06994 06995 if (record_gain) 06996 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06997 06998 06999 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 07000 *duration = atoi(duration_str); 07001 07002 if (prepend_duration) { 07003 struct ast_category *msg_cat; 07004 /* need enough space for a maximum-length message duration */ 07005 char duration_buf[12]; 07006 07007 *duration += prepend_duration; 07008 msg_cat = ast_category_get(msg_cfg, "message"); 07009 snprintf(duration_buf, 11, "%ld", *duration); 07010 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 07011 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 07012 } 07013 } 07014 07015 #endif 07016 break; 07017 case '2': 07018 /* NULL out introfile so we know there is no intro! */ 07019 #ifdef IMAP_STORAGE 07020 *vms->introfn = '\0'; 07021 #endif 07022 cmd = 't'; 07023 break; 07024 case '*': 07025 cmd = '*'; 07026 break; 07027 default: 07028 /* If time_out and return to menu, reset already_recorded */ 07029 already_recorded = 0; 07030 07031 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 07032 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 07033 if (!cmd) { 07034 cmd = ast_play_and_wait(chan, "vm-starmain"); 07035 /* "press star to return to the main menu" */ 07036 } 07037 if (!cmd) { 07038 cmd = ast_waitfordigit(chan, 6000); 07039 } 07040 if (!cmd) { 07041 retries++; 07042 } 07043 if (retries > 3) { 07044 cmd = '*'; /* Let's cancel this beast */ 07045 } 07046 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07047 } 07048 } 07049 07050 if (valid_config(msg_cfg)) 07051 ast_config_destroy(msg_cfg); 07052 if (prepend_duration) 07053 *duration = prepend_duration; 07054 07055 if (already_recorded && cmd == -1) { 07056 /* restore original message if prepention cancelled */ 07057 ast_filerename(backup, msgfile, NULL); 07058 rename(backup_textfile, textfile); 07059 } 07060 07061 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 07062 cmd = 0; 07063 return cmd; 07064 }
static int vm_instructions | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms, | |||
int | skipadvanced, | |||
int | in_urgent | |||
) | [static] |
Definition at line 9264 of file app_voicemail.c.
References vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
09265 { 09266 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09267 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09268 } else { /* Default to ENGLISH */ 09269 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09270 } 09271 }
static int vm_instructions_en | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms, | |||
int | skipadvanced, | |||
int | in_urgent | |||
) | [static] |
Definition at line 9152 of file app_voicemail.c.
References ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_test_flag, ast_waitfordigit(), vm_state::curmsg, vm_state::deleted, vm_state::lastmsg, vm_state::newmessages, vm_state::repeats, vm_state::starting, vm_state::urgentmessages, VM_MESSAGEWRAP, vm_play_folder_name(), and vm_state::vmbox.
Referenced by vm_instructions(), and vm_instructions_zh().
09153 { 09154 int res = 0; 09155 /* Play instructions and wait for new command */ 09156 while (!res) { 09157 if (vms->starting) { 09158 if (vms->lastmsg > -1) { 09159 if (skipadvanced) 09160 res = ast_play_and_wait(chan, "vm-onefor-full"); 09161 else 09162 res = ast_play_and_wait(chan, "vm-onefor"); 09163 if (!res) 09164 res = vm_play_folder_name(chan, vms->vmbox); 09165 } 09166 if (!res) { 09167 if (skipadvanced) 09168 res = ast_play_and_wait(chan, "vm-opts-full"); 09169 else 09170 res = ast_play_and_wait(chan, "vm-opts"); 09171 } 09172 } else { 09173 /* Added for additional help */ 09174 if (skipadvanced) { 09175 res = ast_play_and_wait(chan, "vm-onefor-full"); 09176 if (!res) 09177 res = vm_play_folder_name(chan, vms->vmbox); 09178 res = ast_play_and_wait(chan, "vm-opts-full"); 09179 } 09180 /* Logic: 09181 * If the current message is not the first OR 09182 * if we're listening to the first new message and there are 09183 * also urgent messages, then prompt for navigation to the 09184 * previous message 09185 */ 09186 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09187 res = ast_play_and_wait(chan, "vm-prev"); 09188 } 09189 if (!res && !skipadvanced) 09190 res = ast_play_and_wait(chan, "vm-advopts"); 09191 if (!res) 09192 res = ast_play_and_wait(chan, "vm-repeat"); 09193 /* Logic: 09194 * If we're not listening to the last message OR 09195 * we're listening to the last urgent message and there are 09196 * also new non-urgent messages, then prompt for navigation 09197 * to the next message 09198 */ 09199 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09200 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09201 res = ast_play_and_wait(chan, "vm-next"); 09202 } 09203 if (!res) { 09204 int curmsg_deleted; 09205 #ifdef IMAP_STORAGE 09206 ast_mutex_lock(&vms->lock); 09207 #endif 09208 curmsg_deleted = vms->deleted[vms->curmsg]; 09209 #ifdef IMAP_STORAGE 09210 ast_mutex_unlock(&vms->lock); 09211 #endif 09212 if (!curmsg_deleted) { 09213 res = ast_play_and_wait(chan, "vm-delete"); 09214 } else { 09215 res = ast_play_and_wait(chan, "vm-undelete"); 09216 } 09217 if (!res) { 09218 res = ast_play_and_wait(chan, "vm-toforward"); 09219 } 09220 if (!res) { 09221 res = ast_play_and_wait(chan, "vm-savemessage"); 09222 } 09223 } 09224 } 09225 if (!res) { 09226 res = ast_play_and_wait(chan, "vm-helpexit"); 09227 } 09228 if (!res) 09229 res = ast_waitfordigit(chan, 6000); 09230 if (!res) { 09231 vms->repeats++; 09232 if (vms->repeats > 2) { 09233 res = 't'; 09234 } 09235 } 09236 } 09237 return res; 09238 }
static int vm_instructions_zh | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms, | |||
int | skipadvanced, | |||
int | in_urgent | |||
) | [static] |
Definition at line 9240 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::lastmsg, vm_state::starting, vm_instructions_en(), vm_play_folder_name(), and vm_state::vmbox.
Referenced by vm_instructions().
09241 { 09242 int res = 0; 09243 /* Play instructions and wait for new command */ 09244 while (!res) { 09245 if (vms->lastmsg > -1) { 09246 res = ast_play_and_wait(chan, "vm-listen"); 09247 if (!res) 09248 res = vm_play_folder_name(chan, vms->vmbox); 09249 if (!res) 09250 res = ast_play_and_wait(chan, "press"); 09251 if (!res) 09252 res = ast_play_and_wait(chan, "digits/1"); 09253 } 09254 if (!res) 09255 res = ast_play_and_wait(chan, "vm-opts"); 09256 if (!res) { 09257 vms->starting = 0; 09258 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09259 } 09260 } 09261 return res; 09262 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 9090 of file app_voicemail.c.
References ast_fileexists(), ast_log(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, DISPOSE, LOG_WARNING, ast_vm_user::mailbox, RETRIEVE, vm_state::username, vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_he(), vm_intro_it(), vm_intro_multilang(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_se(), vm_intro_vi(), vm_intro_zh(), VM_SPOOL_DIR, and VM_TEMPGREETWARN.
Referenced by vm_execmain().
09091 { 09092 char prefile[256]; 09093 09094 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09095 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09096 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09097 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09098 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09099 ast_play_and_wait(chan, "vm-tempgreetactive"); 09100 } 09101 DISPOSE(prefile, -1); 09102 } 09103 09104 /* Play voicemail intro - syntax is different for different languages */ 09105 if (0) { 09106 return 0; 09107 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09108 return vm_intro_cs(chan, vms); 09109 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09110 static int deprecation_warning = 0; 09111 if (deprecation_warning++ % 10 == 0) { 09112 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09113 } 09114 return vm_intro_cs(chan, vms); 09115 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09116 return vm_intro_de(chan, vms); 09117 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09118 return vm_intro_es(chan, vms); 09119 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09120 return vm_intro_fr(chan, vms); 09121 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09122 return vm_intro_gr(chan, vms); 09123 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09124 return vm_intro_he(chan, vms); 09125 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09126 return vm_intro_it(chan, vms); 09127 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09128 return vm_intro_nl(chan, vms); 09129 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09130 return vm_intro_no(chan, vms); 09131 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09132 return vm_intro_pl(chan, vms); 09133 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09134 return vm_intro_pt_BR(chan, vms); 09135 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09136 return vm_intro_pt(chan, vms); 09137 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09138 return vm_intro_multilang(chan, vms, "n"); 09139 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09140 return vm_intro_se(chan, vms); 09141 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09142 return vm_intro_multilang(chan, vms, "n"); 09143 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09144 return vm_intro_vi(chan, vms); 09145 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09146 return vm_intro_zh(chan, vms); 09147 } else { /* Default to ENGLISH */ 09148 return vm_intro_en(chan, vms); 09149 } 09150 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8960 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08961 { 08962 int res; 08963 res = ast_play_and_wait(chan, "vm-youhave"); 08964 if (!res) { 08965 if (vms->newmessages) { 08966 if (vms->newmessages == 1) { 08967 res = ast_play_and_wait(chan, "digits/jednu"); 08968 } else { 08969 res = say_and_wait(chan, vms->newmessages, chan->language); 08970 } 08971 if (!res) { 08972 if ((vms->newmessages == 1)) 08973 res = ast_play_and_wait(chan, "vm-novou"); 08974 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08975 res = ast_play_and_wait(chan, "vm-nove"); 08976 if (vms->newmessages > 4) 08977 res = ast_play_and_wait(chan, "vm-novych"); 08978 } 08979 if (vms->oldmessages && !res) 08980 res = ast_play_and_wait(chan, "vm-and"); 08981 else if (!res) { 08982 if ((vms->newmessages == 1)) 08983 res = ast_play_and_wait(chan, "vm-zpravu"); 08984 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08985 res = ast_play_and_wait(chan, "vm-zpravy"); 08986 if (vms->newmessages > 4) 08987 res = ast_play_and_wait(chan, "vm-zprav"); 08988 } 08989 } 08990 if (!res && vms->oldmessages) { 08991 res = say_and_wait(chan, vms->oldmessages, chan->language); 08992 if (!res) { 08993 if ((vms->oldmessages == 1)) 08994 res = ast_play_and_wait(chan, "vm-starou"); 08995 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08996 res = ast_play_and_wait(chan, "vm-stare"); 08997 if (vms->oldmessages > 4) 08998 res = ast_play_and_wait(chan, "vm-starych"); 08999 } 09000 if (!res) { 09001 if ((vms->oldmessages == 1)) 09002 res = ast_play_and_wait(chan, "vm-zpravu"); 09003 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 09004 res = ast_play_and_wait(chan, "vm-zpravy"); 09005 if (vms->oldmessages > 4) 09006 res = ast_play_and_wait(chan, "vm-zprav"); 09007 } 09008 } 09009 if (!res) { 09010 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 09011 res = ast_play_and_wait(chan, "vm-no"); 09012 if (!res) 09013 res = ast_play_and_wait(chan, "vm-zpravy"); 09014 } 09015 } 09016 } 09017 return res; 09018 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8656 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08657 { 08658 /* Introduce messages they have */ 08659 int res; 08660 res = ast_play_and_wait(chan, "vm-youhave"); 08661 if (!res) { 08662 if (vms->newmessages) { 08663 if ((vms->newmessages == 1)) 08664 res = ast_play_and_wait(chan, "digits/1F"); 08665 else 08666 res = say_and_wait(chan, vms->newmessages, chan->language); 08667 if (!res) 08668 res = ast_play_and_wait(chan, "vm-INBOX"); 08669 if (vms->oldmessages && !res) 08670 res = ast_play_and_wait(chan, "vm-and"); 08671 else if (!res) { 08672 if ((vms->newmessages == 1)) 08673 res = ast_play_and_wait(chan, "vm-message"); 08674 else 08675 res = ast_play_and_wait(chan, "vm-messages"); 08676 } 08677 08678 } 08679 if (!res && vms->oldmessages) { 08680 if (vms->oldmessages == 1) 08681 res = ast_play_and_wait(chan, "digits/1F"); 08682 else 08683 res = say_and_wait(chan, vms->oldmessages, chan->language); 08684 if (!res) 08685 res = ast_play_and_wait(chan, "vm-Old"); 08686 if (!res) { 08687 if (vms->oldmessages == 1) 08688 res = ast_play_and_wait(chan, "vm-message"); 08689 else 08690 res = ast_play_and_wait(chan, "vm-messages"); 08691 } 08692 } 08693 if (!res) { 08694 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08695 res = ast_play_and_wait(chan, "vm-no"); 08696 if (!res) 08697 res = ast_play_and_wait(chan, "vm-messages"); 08698 } 08699 } 08700 } 08701 return res; 08702 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8405 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08406 { 08407 int res; 08408 08409 /* Introduce messages they have */ 08410 res = ast_play_and_wait(chan, "vm-youhave"); 08411 if (!res) { 08412 if (vms->urgentmessages) { 08413 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08414 if (!res) 08415 res = ast_play_and_wait(chan, "vm-Urgent"); 08416 if ((vms->oldmessages || vms->newmessages) && !res) { 08417 res = ast_play_and_wait(chan, "vm-and"); 08418 } else if (!res) { 08419 if ((vms->urgentmessages == 1)) 08420 res = ast_play_and_wait(chan, "vm-message"); 08421 else 08422 res = ast_play_and_wait(chan, "vm-messages"); 08423 } 08424 } 08425 if (vms->newmessages) { 08426 res = say_and_wait(chan, vms->newmessages, chan->language); 08427 if (!res) 08428 res = ast_play_and_wait(chan, "vm-INBOX"); 08429 if (vms->oldmessages && !res) 08430 res = ast_play_and_wait(chan, "vm-and"); 08431 else if (!res) { 08432 if ((vms->newmessages == 1)) 08433 res = ast_play_and_wait(chan, "vm-message"); 08434 else 08435 res = ast_play_and_wait(chan, "vm-messages"); 08436 } 08437 08438 } 08439 if (!res && vms->oldmessages) { 08440 res = say_and_wait(chan, vms->oldmessages, chan->language); 08441 if (!res) 08442 res = ast_play_and_wait(chan, "vm-Old"); 08443 if (!res) { 08444 if (vms->oldmessages == 1) 08445 res = ast_play_and_wait(chan, "vm-message"); 08446 else 08447 res = ast_play_and_wait(chan, "vm-messages"); 08448 } 08449 } 08450 if (!res) { 08451 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08452 res = ast_play_and_wait(chan, "vm-no"); 08453 if (!res) 08454 res = ast_play_and_wait(chan, "vm-messages"); 08455 } 08456 } 08457 } 08458 return res; 08459 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8705 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08706 { 08707 /* Introduce messages they have */ 08708 int res; 08709 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08710 res = ast_play_and_wait(chan, "vm-youhaveno"); 08711 if (!res) 08712 res = ast_play_and_wait(chan, "vm-messages"); 08713 } else { 08714 res = ast_play_and_wait(chan, "vm-youhave"); 08715 } 08716 if (!res) { 08717 if (vms->newmessages) { 08718 if (!res) { 08719 if ((vms->newmessages == 1)) { 08720 res = ast_play_and_wait(chan, "digits/1"); 08721 if (!res) 08722 res = ast_play_and_wait(chan, "vm-message"); 08723 if (!res) 08724 res = ast_play_and_wait(chan, "vm-INBOXs"); 08725 } else { 08726 res = say_and_wait(chan, vms->newmessages, chan->language); 08727 if (!res) 08728 res = ast_play_and_wait(chan, "vm-messages"); 08729 if (!res) 08730 res = ast_play_and_wait(chan, "vm-INBOX"); 08731 } 08732 } 08733 if (vms->oldmessages && !res) 08734 res = ast_play_and_wait(chan, "vm-and"); 08735 } 08736 if (vms->oldmessages) { 08737 if (!res) { 08738 if (vms->oldmessages == 1) { 08739 res = ast_play_and_wait(chan, "digits/1"); 08740 if (!res) 08741 res = ast_play_and_wait(chan, "vm-message"); 08742 if (!res) 08743 res = ast_play_and_wait(chan, "vm-Olds"); 08744 } else { 08745 res = say_and_wait(chan, vms->oldmessages, chan->language); 08746 if (!res) 08747 res = ast_play_and_wait(chan, "vm-messages"); 08748 if (!res) 08749 res = ast_play_and_wait(chan, "vm-Old"); 08750 } 08751 } 08752 } 08753 } 08754 return res; 08755 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8803 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08804 { 08805 /* Introduce messages they have */ 08806 int res; 08807 res = ast_play_and_wait(chan, "vm-youhave"); 08808 if (!res) { 08809 if (vms->newmessages) { 08810 res = say_and_wait(chan, vms->newmessages, chan->language); 08811 if (!res) 08812 res = ast_play_and_wait(chan, "vm-INBOX"); 08813 if (vms->oldmessages && !res) 08814 res = ast_play_and_wait(chan, "vm-and"); 08815 else if (!res) { 08816 if ((vms->newmessages == 1)) 08817 res = ast_play_and_wait(chan, "vm-message"); 08818 else 08819 res = ast_play_and_wait(chan, "vm-messages"); 08820 } 08821 08822 } 08823 if (!res && vms->oldmessages) { 08824 res = say_and_wait(chan, vms->oldmessages, chan->language); 08825 if (!res) 08826 res = ast_play_and_wait(chan, "vm-Old"); 08827 if (!res) { 08828 if (vms->oldmessages == 1) 08829 res = ast_play_and_wait(chan, "vm-message"); 08830 else 08831 res = ast_play_and_wait(chan, "vm-messages"); 08832 } 08833 } 08834 if (!res) { 08835 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08836 res = ast_play_and_wait(chan, "vm-no"); 08837 if (!res) 08838 res = ast_play_and_wait(chan, "vm-messages"); 08839 } 08840 } 08841 } 08842 return res; 08843 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8204 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08205 { 08206 int res = 0; 08207 08208 if (vms->newmessages) { 08209 res = ast_play_and_wait(chan, "vm-youhave"); 08210 if (!res) 08211 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08212 if (!res) { 08213 if ((vms->newmessages == 1)) { 08214 res = ast_play_and_wait(chan, "vm-INBOX"); 08215 if (!res) 08216 res = ast_play_and_wait(chan, "vm-message"); 08217 } else { 08218 res = ast_play_and_wait(chan, "vm-INBOXs"); 08219 if (!res) 08220 res = ast_play_and_wait(chan, "vm-messages"); 08221 } 08222 } 08223 } else if (vms->oldmessages){ 08224 res = ast_play_and_wait(chan, "vm-youhave"); 08225 if (!res) 08226 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08227 if ((vms->oldmessages == 1)){ 08228 res = ast_play_and_wait(chan, "vm-Old"); 08229 if (!res) 08230 res = ast_play_and_wait(chan, "vm-message"); 08231 } else { 08232 res = ast_play_and_wait(chan, "vm-Olds"); 08233 if (!res) 08234 res = ast_play_and_wait(chan, "vm-messages"); 08235 } 08236 } else if (!vms->oldmessages && !vms->newmessages) 08237 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08238 return res; 08239 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8338 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08339 { 08340 int res = 0; 08341 08342 /* Introduce messages they have */ 08343 if (!res) { 08344 if ((vms->newmessages) || (vms->oldmessages)) { 08345 res = ast_play_and_wait(chan, "vm-youhave"); 08346 } 08347 /* 08348 * The word "shtei" refers to the number 2 in hebrew when performing a count 08349 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08350 * an element, this is one of them. 08351 */ 08352 if (vms->newmessages) { 08353 if (!res) { 08354 if (vms->newmessages == 1) { 08355 res = ast_play_and_wait(chan, "vm-INBOX1"); 08356 } else { 08357 if (vms->newmessages == 2) { 08358 res = ast_play_and_wait(chan, "vm-shtei"); 08359 } else { 08360 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08361 } 08362 res = ast_play_and_wait(chan, "vm-INBOX"); 08363 } 08364 } 08365 if (vms->oldmessages && !res) { 08366 res = ast_play_and_wait(chan, "vm-and"); 08367 if (vms->oldmessages == 1) { 08368 res = ast_play_and_wait(chan, "vm-Old1"); 08369 } else { 08370 if (vms->oldmessages == 2) { 08371 res = ast_play_and_wait(chan, "vm-shtei"); 08372 } else { 08373 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08374 } 08375 res = ast_play_and_wait(chan, "vm-Old"); 08376 } 08377 } 08378 } 08379 if (!res && vms->oldmessages && !vms->newmessages) { 08380 if (!res) { 08381 if (vms->oldmessages == 1) { 08382 res = ast_play_and_wait(chan, "vm-Old1"); 08383 } else { 08384 if (vms->oldmessages == 2) { 08385 res = ast_play_and_wait(chan, "vm-shtei"); 08386 } else { 08387 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08388 } 08389 res = ast_play_and_wait(chan, "vm-Old"); 08390 } 08391 } 08392 } 08393 if (!res) { 08394 if (!vms->oldmessages && !vms->newmessages) { 08395 if (!res) { 08396 res = ast_play_and_wait(chan, "vm-nomessages"); 08397 } 08398 } 08399 } 08400 } 08401 return res; 08402 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8462 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08463 { 08464 /* Introduce messages they have */ 08465 int res; 08466 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08467 res = ast_play_and_wait(chan, "vm-no") || 08468 ast_play_and_wait(chan, "vm-message"); 08469 else 08470 res = ast_play_and_wait(chan, "vm-youhave"); 08471 if (!res && vms->newmessages) { 08472 res = (vms->newmessages == 1) ? 08473 ast_play_and_wait(chan, "digits/un") || 08474 ast_play_and_wait(chan, "vm-nuovo") || 08475 ast_play_and_wait(chan, "vm-message") : 08476 /* 2 or more new messages */ 08477 say_and_wait(chan, vms->newmessages, chan->language) || 08478 ast_play_and_wait(chan, "vm-nuovi") || 08479 ast_play_and_wait(chan, "vm-messages"); 08480 if (!res && vms->oldmessages) 08481 res = ast_play_and_wait(chan, "vm-and"); 08482 } 08483 if (!res && vms->oldmessages) { 08484 res = (vms->oldmessages == 1) ? 08485 ast_play_and_wait(chan, "digits/un") || 08486 ast_play_and_wait(chan, "vm-vecchio") || 08487 ast_play_and_wait(chan, "vm-message") : 08488 /* 2 or more old messages */ 08489 say_and_wait(chan, vms->oldmessages, chan->language) || 08490 ast_play_and_wait(chan, "vm-vecchi") || 08491 ast_play_and_wait(chan, "vm-messages"); 08492 } 08493 return res; 08494 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8298 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_counted_adjective(), ast_say_counted_noun(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08299 { 08300 int res; 08301 int lastnum = 0; 08302 08303 res = ast_play_and_wait(chan, "vm-youhave"); 08304 08305 if (!res && vms->newmessages) { 08306 lastnum = vms->newmessages; 08307 08308 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08309 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08310 } 08311 08312 if (!res && vms->oldmessages) { 08313 res = ast_play_and_wait(chan, "vm-and"); 08314 } 08315 } 08316 08317 if (!res && vms->oldmessages) { 08318 lastnum = vms->oldmessages; 08319 08320 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08321 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08322 } 08323 } 08324 08325 if (!res) { 08326 if (lastnum == 0) { 08327 res = ast_play_and_wait(chan, "vm-no"); 08328 } 08329 if (!res) { 08330 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08331 } 08332 } 08333 08334 return res; 08335 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8846 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08847 { 08848 /* Introduce messages they have */ 08849 int res; 08850 res = ast_play_and_wait(chan, "vm-youhave"); 08851 if (!res) { 08852 if (vms->newmessages) { 08853 res = say_and_wait(chan, vms->newmessages, chan->language); 08854 if (!res) { 08855 if (vms->newmessages == 1) 08856 res = ast_play_and_wait(chan, "vm-INBOXs"); 08857 else 08858 res = ast_play_and_wait(chan, "vm-INBOX"); 08859 } 08860 if (vms->oldmessages && !res) 08861 res = ast_play_and_wait(chan, "vm-and"); 08862 else if (!res) { 08863 if ((vms->newmessages == 1)) 08864 res = ast_play_and_wait(chan, "vm-message"); 08865 else 08866 res = ast_play_and_wait(chan, "vm-messages"); 08867 } 08868 08869 } 08870 if (!res && vms->oldmessages) { 08871 res = say_and_wait(chan, vms->oldmessages, chan->language); 08872 if (!res) { 08873 if (vms->oldmessages == 1) 08874 res = ast_play_and_wait(chan, "vm-Olds"); 08875 else 08876 res = ast_play_and_wait(chan, "vm-Old"); 08877 } 08878 if (!res) { 08879 if (vms->oldmessages == 1) 08880 res = ast_play_and_wait(chan, "vm-message"); 08881 else 08882 res = ast_play_and_wait(chan, "vm-messages"); 08883 } 08884 } 08885 if (!res) { 08886 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08887 res = ast_play_and_wait(chan, "vm-no"); 08888 if (!res) 08889 res = ast_play_and_wait(chan, "vm-messages"); 08890 } 08891 } 08892 } 08893 return res; 08894 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8612 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08613 { 08614 /* Introduce messages they have */ 08615 int res; 08616 08617 res = ast_play_and_wait(chan, "vm-youhave"); 08618 if (res) 08619 return res; 08620 08621 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08622 res = ast_play_and_wait(chan, "vm-no"); 08623 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08624 return res; 08625 } 08626 08627 if (vms->newmessages) { 08628 if ((vms->newmessages == 1)) { 08629 res = ast_play_and_wait(chan, "digits/1"); 08630 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08631 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08632 } else { 08633 res = say_and_wait(chan, vms->newmessages, chan->language); 08634 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08635 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08636 } 08637 if (!res && vms->oldmessages) 08638 res = ast_play_and_wait(chan, "vm-and"); 08639 } 08640 if (!res && vms->oldmessages) { 08641 if (vms->oldmessages == 1) { 08642 res = ast_play_and_wait(chan, "digits/1"); 08643 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08644 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08645 } else { 08646 res = say_and_wait(chan, vms->oldmessages, chan->language); 08647 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08648 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08649 } 08650 } 08651 08652 return res; 08653 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8497 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08498 { 08499 /* Introduce messages they have */ 08500 int res; 08501 div_t num; 08502 08503 if (!vms->oldmessages && !vms->newmessages) { 08504 res = ast_play_and_wait(chan, "vm-no"); 08505 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08506 return res; 08507 } else { 08508 res = ast_play_and_wait(chan, "vm-youhave"); 08509 } 08510 08511 if (vms->newmessages) { 08512 num = div(vms->newmessages, 10); 08513 if (vms->newmessages == 1) { 08514 res = ast_play_and_wait(chan, "digits/1-a"); 08515 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08516 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08517 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08518 if (num.rem == 2) { 08519 if (!num.quot) { 08520 res = ast_play_and_wait(chan, "digits/2-ie"); 08521 } else { 08522 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08523 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08524 } 08525 } else { 08526 res = say_and_wait(chan, vms->newmessages, chan->language); 08527 } 08528 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08529 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08530 } else { 08531 res = say_and_wait(chan, vms->newmessages, chan->language); 08532 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08533 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08534 } 08535 if (!res && vms->oldmessages) 08536 res = ast_play_and_wait(chan, "vm-and"); 08537 } 08538 if (!res && vms->oldmessages) { 08539 num = div(vms->oldmessages, 10); 08540 if (vms->oldmessages == 1) { 08541 res = ast_play_and_wait(chan, "digits/1-a"); 08542 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08543 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08544 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08545 if (num.rem == 2) { 08546 if (!num.quot) { 08547 res = ast_play_and_wait(chan, "digits/2-ie"); 08548 } else { 08549 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08550 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08551 } 08552 } else { 08553 res = say_and_wait(chan, vms->oldmessages, chan->language); 08554 } 08555 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08556 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08557 } else { 08558 res = say_and_wait(chan, vms->oldmessages, chan->language); 08559 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08560 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08561 } 08562 } 08563 08564 return res; 08565 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8897 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
08898 { 08899 /* Introduce messages they have */ 08900 int res; 08901 res = ast_play_and_wait(chan, "vm-youhave"); 08902 if (!res) { 08903 if (vms->newmessages) { 08904 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08905 if (!res) { 08906 if ((vms->newmessages == 1)) { 08907 res = ast_play_and_wait(chan, "vm-message"); 08908 if (!res) 08909 res = ast_play_and_wait(chan, "vm-INBOXs"); 08910 } else { 08911 res = ast_play_and_wait(chan, "vm-messages"); 08912 if (!res) 08913 res = ast_play_and_wait(chan, "vm-INBOX"); 08914 } 08915 } 08916 if (vms->oldmessages && !res) 08917 res = ast_play_and_wait(chan, "vm-and"); 08918 } 08919 if (!res && vms->oldmessages) { 08920 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08921 if (!res) { 08922 if (vms->oldmessages == 1) { 08923 res = ast_play_and_wait(chan, "vm-message"); 08924 if (!res) 08925 res = ast_play_and_wait(chan, "vm-Olds"); 08926 } else { 08927 res = ast_play_and_wait(chan, "vm-messages"); 08928 if (!res) 08929 res = ast_play_and_wait(chan, "vm-Old"); 08930 } 08931 } 08932 } 08933 if (!res) { 08934 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08935 res = ast_play_and_wait(chan, "vm-no"); 08936 if (!res) 08937 res = ast_play_and_wait(chan, "vm-messages"); 08938 } 08939 } 08940 } 08941 return res; 08942 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8758 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
08758 { 08759 /* Introduce messages they have */ 08760 int res; 08761 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08762 res = ast_play_and_wait(chan, "vm-nomessages"); 08763 return res; 08764 } else { 08765 res = ast_play_and_wait(chan, "vm-youhave"); 08766 } 08767 if (vms->newmessages) { 08768 if (!res) 08769 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08770 if ((vms->newmessages == 1)) { 08771 if (!res) 08772 res = ast_play_and_wait(chan, "vm-message"); 08773 if (!res) 08774 res = ast_play_and_wait(chan, "vm-INBOXs"); 08775 } else { 08776 if (!res) 08777 res = ast_play_and_wait(chan, "vm-messages"); 08778 if (!res) 08779 res = ast_play_and_wait(chan, "vm-INBOX"); 08780 } 08781 if (vms->oldmessages && !res) 08782 res = ast_play_and_wait(chan, "vm-and"); 08783 } 08784 if (vms->oldmessages) { 08785 if (!res) 08786 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08787 if (vms->oldmessages == 1) { 08788 if (!res) 08789 res = ast_play_and_wait(chan, "vm-message"); 08790 if (!res) 08791 res = ast_play_and_wait(chan, "vm-Olds"); 08792 } else { 08793 if (!res) 08794 res = ast_play_and_wait(chan, "vm-messages"); 08795 if (!res) 08796 res = ast_play_and_wait(chan, "vm-Old"); 08797 } 08798 } 08799 return res; 08800 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8568 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08569 { 08570 /* Introduce messages they have */ 08571 int res; 08572 08573 res = ast_play_and_wait(chan, "vm-youhave"); 08574 if (res) 08575 return res; 08576 08577 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08578 res = ast_play_and_wait(chan, "vm-no"); 08579 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08580 return res; 08581 } 08582 08583 if (vms->newmessages) { 08584 if ((vms->newmessages == 1)) { 08585 res = ast_play_and_wait(chan, "digits/ett"); 08586 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08587 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08588 } else { 08589 res = say_and_wait(chan, vms->newmessages, chan->language); 08590 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08591 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08592 } 08593 if (!res && vms->oldmessages) 08594 res = ast_play_and_wait(chan, "vm-and"); 08595 } 08596 if (!res && vms->oldmessages) { 08597 if (vms->oldmessages == 1) { 08598 res = ast_play_and_wait(chan, "digits/ett"); 08599 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08600 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08601 } else { 08602 res = say_and_wait(chan, vms->oldmessages, chan->language); 08603 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08604 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08605 } 08606 } 08607 08608 return res; 08609 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 9060 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
09061 { 09062 int res; 09063 09064 /* Introduce messages they have */ 09065 res = ast_play_and_wait(chan, "vm-youhave"); 09066 if (!res) { 09067 if (vms->newmessages) { 09068 res = say_and_wait(chan, vms->newmessages, chan->language); 09069 if (!res) 09070 res = ast_play_and_wait(chan, "vm-INBOX"); 09071 if (vms->oldmessages && !res) 09072 res = ast_play_and_wait(chan, "vm-and"); 09073 } 09074 if (!res && vms->oldmessages) { 09075 res = say_and_wait(chan, vms->oldmessages, chan->language); 09076 if (!res) 09077 res = ast_play_and_wait(chan, "vm-Old"); 09078 } 09079 if (!res) { 09080 if (!vms->oldmessages && !vms->newmessages) { 09081 res = ast_play_and_wait(chan, "vm-no"); 09082 if (!res) 09083 res = ast_play_and_wait(chan, "vm-message"); 09084 } 09085 } 09086 } 09087 return res; 09088 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 9021 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
09022 { 09023 int res; 09024 /* Introduce messages they have */ 09025 res = ast_play_and_wait(chan, "vm-you"); 09026 09027 if (!res && vms->newmessages) { 09028 res = ast_play_and_wait(chan, "vm-have"); 09029 if (!res) 09030 res = say_and_wait(chan, vms->newmessages, chan->language); 09031 if (!res) 09032 res = ast_play_and_wait(chan, "vm-tong"); 09033 if (!res) 09034 res = ast_play_and_wait(chan, "vm-INBOX"); 09035 if (vms->oldmessages && !res) 09036 res = ast_play_and_wait(chan, "vm-and"); 09037 else if (!res) 09038 res = ast_play_and_wait(chan, "vm-messages"); 09039 } 09040 if (!res && vms->oldmessages) { 09041 res = ast_play_and_wait(chan, "vm-have"); 09042 if (!res) 09043 res = say_and_wait(chan, vms->oldmessages, chan->language); 09044 if (!res) 09045 res = ast_play_and_wait(chan, "vm-tong"); 09046 if (!res) 09047 res = ast_play_and_wait(chan, "vm-Old"); 09048 if (!res) 09049 res = ast_play_and_wait(chan, "vm-messages"); 09050 } 09051 if (!res && !vms->oldmessages && !vms->newmessages) { 09052 res = ast_play_and_wait(chan, "vm-haveno"); 09053 if (!res) 09054 res = ast_play_and_wait(chan, "vm-messages"); 09055 } 09056 return res; 09057 }
static int vm_lock_path | ( | const char * | path | ) | [static] |
Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason.
Definition at line 3304 of file app_voicemail.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
Referenced by close_mailbox(), copy_message(), count_messages(), leave_voicemail(), open_mailbox(), resequence_mailbox(), and save_to_folder().
03305 { 03306 switch (ast_lock_path(path)) { 03307 case AST_LOCK_TIMEOUT: 03308 return -1; 03309 default: 03310 return 0; 03311 } 03312 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1675 of file app_voicemail.c.
References my_umask, and VOICEMAIL_FILE_MODE.
Referenced by sendmail(), and sendpage().
01676 { 01677 FILE *p = NULL; 01678 int pfd = mkstemp(template); 01679 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01680 if (pfd > -1) { 01681 p = fdopen(pfd, "w+"); 01682 if (!p) { 01683 close(pfd); 01684 pfd = -1; 01685 } 01686 } 01687 return p; 01688 }
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 9274 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_debug, ast_fileexists(), ast_log(), AST_LOG_NOTICE, ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, check_password(), ast_vm_user::context, ext_pass_cmd, maxgreet, play_record_review(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, VM_FORCENAME, vm_invalid_password, vm_mismatch, vm_newpassword, vm_passchanged, vm_pls_try_again, vm_reenterpassword, and VM_SPOOL_DIR.
Referenced by vm_execmain().
09275 { 09276 int cmd = 0; 09277 int duration = 0; 09278 int tries = 0; 09279 char newpassword[80] = ""; 09280 char newpassword2[80] = ""; 09281 char prefile[PATH_MAX] = ""; 09282 unsigned char buf[256]; 09283 int bytes = 0; 09284 09285 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09286 if (ast_adsi_available(chan)) { 09287 bytes += adsi_logo(buf + bytes); 09288 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09289 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09290 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09291 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09292 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09293 } 09294 09295 /* If forcename is set, have the user record their name */ 09296 if (ast_test_flag(vmu, VM_FORCENAME)) { 09297 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09298 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09299 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09300 if (cmd < 0 || cmd == 't' || cmd == '#') 09301 return cmd; 09302 } 09303 } 09304 09305 /* If forcegreetings is set, have the user record their greetings */ 09306 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09307 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09308 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09309 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09310 if (cmd < 0 || cmd == 't' || cmd == '#') 09311 return cmd; 09312 } 09313 09314 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09315 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09316 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09317 if (cmd < 0 || cmd == 't' || cmd == '#') 09318 return cmd; 09319 } 09320 } 09321 09322 /* 09323 * Change the password last since new users will be able to skip over any steps this one comes before 09324 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09325 */ 09326 for (;;) { 09327 newpassword[1] = '\0'; 09328 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09329 if (cmd == '#') 09330 newpassword[0] = '\0'; 09331 if (cmd < 0 || cmd == 't' || cmd == '#') 09332 return cmd; 09333 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09334 if (cmd < 0 || cmd == 't' || cmd == '#') 09335 return cmd; 09336 cmd = check_password(vmu, newpassword); /* perform password validation */ 09337 if (cmd != 0) { 09338 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09339 cmd = ast_play_and_wait(chan, vm_invalid_password); 09340 } else { 09341 newpassword2[1] = '\0'; 09342 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09343 if (cmd == '#') 09344 newpassword2[0] = '\0'; 09345 if (cmd < 0 || cmd == 't' || cmd == '#') 09346 return cmd; 09347 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09348 if (cmd < 0 || cmd == 't' || cmd == '#') 09349 return cmd; 09350 if (!strcmp(newpassword, newpassword2)) 09351 break; 09352 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09353 cmd = ast_play_and_wait(chan, vm_mismatch); 09354 } 09355 if (++tries == 3) 09356 return -1; 09357 if (cmd != 0) { 09358 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09359 } 09360 } 09361 if (pwdchange & PWDCHANGE_INTERNAL) 09362 vm_change_password(vmu, newpassword); 09363 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09364 vm_change_password_shell(vmu, newpassword); 09365 09366 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09367 cmd = ast_play_and_wait(chan, vm_passchanged); 09368 09369 return cmd; 09370 }
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 9372 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_debug, ast_fileexists(), ast_log(), AST_LOG_NOTICE, ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_suite_event_notify, ast_waitfordigit(), check_password(), ast_vm_user::context, DISPOSE, ext_pass_cmd, ast_vm_user::mailbox, maxgreet, ast_vm_user::password, play_record_review(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, RETRIEVE, vm_state::username, vm_change_password(), vm_change_password_shell(), vm_invalid_password, vm_mismatch, vm_newpassword, vm_passchanged, vm_pls_try_again, vm_reenterpassword, VM_SPOOL_DIR, and vm_tempgreeting().
Referenced by vm_execmain().
09373 { 09374 int cmd = 0; 09375 int retries = 0; 09376 int duration = 0; 09377 char newpassword[80] = ""; 09378 char newpassword2[80] = ""; 09379 char prefile[PATH_MAX] = ""; 09380 unsigned char buf[256]; 09381 int bytes = 0; 09382 09383 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09384 if (ast_adsi_available(chan)) { 09385 bytes += adsi_logo(buf + bytes); 09386 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09387 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09388 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09389 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09390 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09391 } 09392 while ((cmd >= 0) && (cmd != 't')) { 09393 if (cmd) 09394 retries = 0; 09395 switch (cmd) { 09396 case '1': /* Record your unavailable message */ 09397 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09398 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09399 break; 09400 case '2': /* Record your busy message */ 09401 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09402 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09403 break; 09404 case '3': /* Record greeting */ 09405 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09406 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09407 break; 09408 case '4': /* manage the temporary greeting */ 09409 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09410 break; 09411 case '5': /* change password */ 09412 if (vmu->password[0] == '-') { 09413 cmd = ast_play_and_wait(chan, "vm-no"); 09414 break; 09415 } 09416 newpassword[1] = '\0'; 09417 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09418 if (cmd == '#') 09419 newpassword[0] = '\0'; 09420 else { 09421 if (cmd < 0) 09422 break; 09423 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09424 break; 09425 } 09426 } 09427 cmd = check_password(vmu, newpassword); /* perform password validation */ 09428 if (cmd != 0) { 09429 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09430 cmd = ast_play_and_wait(chan, vm_invalid_password); 09431 if (!cmd) { 09432 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09433 } 09434 break; 09435 } 09436 newpassword2[1] = '\0'; 09437 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09438 if (cmd == '#') 09439 newpassword2[0] = '\0'; 09440 else { 09441 if (cmd < 0) 09442 break; 09443 09444 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09445 break; 09446 } 09447 } 09448 if (strcmp(newpassword, newpassword2)) { 09449 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09450 cmd = ast_play_and_wait(chan, vm_mismatch); 09451 if (!cmd) { 09452 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09453 } 09454 break; 09455 } 09456 09457 if (pwdchange & PWDCHANGE_INTERNAL) { 09458 vm_change_password(vmu, newpassword); 09459 } 09460 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09461 vm_change_password_shell(vmu, newpassword); 09462 } 09463 09464 ast_debug(1, "User %s set password to %s of length %d\n", 09465 vms->username, newpassword, (int) strlen(newpassword)); 09466 cmd = ast_play_and_wait(chan, vm_passchanged); 09467 break; 09468 case '*': 09469 cmd = 't'; 09470 break; 09471 default: 09472 cmd = 0; 09473 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09474 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09475 if (ast_fileexists(prefile, NULL, NULL)) { 09476 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09477 } 09478 DISPOSE(prefile, -1); 09479 if (!cmd) { 09480 cmd = ast_play_and_wait(chan, "vm-options"); 09481 } 09482 if (!cmd) { 09483 cmd = ast_waitfordigit(chan, 6000); 09484 } 09485 if (!cmd) { 09486 retries++; 09487 } 09488 if (retries > 3) { 09489 cmd = 't'; 09490 } 09491 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09492 } 09493 } 09494 if (cmd == 't') 09495 cmd = 0; 09496 return cmd; 09497 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 8167 of file app_voicemail.c.
References ast_play_and_wait(), vm_play_folder_name_gr(), vm_play_folder_name_pl(), and vm_play_folder_name_ua().
Referenced by get_folder(), vm_execmain(), vm_instructions_en(), and vm_instructions_zh().
08168 { 08169 int cmd; 08170 08171 if ( !strncasecmp(chan->language, "it", 2) || 08172 !strncasecmp(chan->language, "es", 2) || 08173 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08174 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08175 return cmd ? cmd : ast_play_and_wait(chan, box); 08176 } else if (!strncasecmp(chan->language, "gr", 2)) { 08177 return vm_play_folder_name_gr(chan, box); 08178 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08179 return ast_play_and_wait(chan, box); 08180 } else if (!strncasecmp(chan->language, "pl", 2)) { 08181 return vm_play_folder_name_pl(chan, box); 08182 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08183 return vm_play_folder_name_ua(chan, box); 08184 } else if (!strncasecmp(chan->language, "vi", 2)) { 08185 return ast_play_and_wait(chan, box); 08186 } else { /* Default English */ 08187 cmd = ast_play_and_wait(chan, box); 08188 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08189 } 08190 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8120 of file app_voicemail.c.
References ast_alloca, and ast_play_and_wait().
Referenced by vm_play_folder_name().
08121 { 08122 int cmd; 08123 char *buf; 08124 08125 buf = ast_alloca(strlen(box) + 2); 08126 strcpy(buf, box); 08127 strcat(buf, "s"); 08128 08129 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08130 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08131 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08132 } else { 08133 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08134 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08135 } 08136 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8138 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08139 { 08140 int cmd; 08141 08142 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08143 if (!strcasecmp(box, "vm-INBOX")) 08144 cmd = ast_play_and_wait(chan, "vm-new-e"); 08145 else 08146 cmd = ast_play_and_wait(chan, "vm-old-e"); 08147 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08148 } else { 08149 cmd = ast_play_and_wait(chan, "vm-messages"); 08150 return cmd ? cmd : ast_play_and_wait(chan, box); 08151 } 08152 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8154 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08155 { 08156 int cmd; 08157 08158 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08159 cmd = ast_play_and_wait(chan, "vm-messages"); 08160 return cmd ? cmd : ast_play_and_wait(chan, box); 08161 } else { 08162 cmd = ast_play_and_wait(chan, box); 08163 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08164 } 08165 }
static int vm_tempgreeting | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms, | |||
char * | fmtc, | |||
signed char | record_gain | |||
) | [static] |
The handler for 'record a temporary greeting'.
chan | ||
vmu | ||
vms | ||
fmtc | ||
record_gain | This is option 4 from the mailbox options menu. This function manages the following promptings: 1: play / record / review the temporary greeting. : invokes play_record_review(). 2: remove (delete) the temporary greeting. *: return to the main menu. |
Definition at line 9515 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_play_and_wait(), ast_test_suite_event_notify, ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::mailbox, maxgreet, play_record_review(), RETRIEVE, vm_state::username, and VM_SPOOL_DIR.
Referenced by vm_options().
09516 { 09517 int cmd = 0; 09518 int retries = 0; 09519 int duration = 0; 09520 char prefile[PATH_MAX] = ""; 09521 unsigned char buf[256]; 09522 int bytes = 0; 09523 09524 if (ast_adsi_available(chan)) { 09525 bytes += adsi_logo(buf + bytes); 09526 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09527 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09528 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09529 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09530 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09531 } 09532 09533 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09534 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09535 while ((cmd >= 0) && (cmd != 't')) { 09536 if (cmd) 09537 retries = 0; 09538 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09539 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09540 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09541 if (cmd == -1) { 09542 break; 09543 } 09544 cmd = 't'; 09545 } else { 09546 switch (cmd) { 09547 case '1': 09548 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09549 break; 09550 case '2': 09551 DELETE(prefile, -1, prefile, vmu); 09552 ast_play_and_wait(chan, "vm-tempremoved"); 09553 cmd = 't'; 09554 break; 09555 case '*': 09556 cmd = 't'; 09557 break; 09558 default: 09559 cmd = ast_play_and_wait(chan, 09560 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09561 "vm-tempgreeting2" : "vm-tempgreeting"); 09562 if (!cmd) { 09563 cmd = ast_waitfordigit(chan, 6000); 09564 } 09565 if (!cmd) { 09566 retries++; 09567 } 09568 if (retries > 3) { 09569 cmd = 't'; 09570 } 09571 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09572 } 09573 } 09574 DISPOSE(prefile, -1); 09575 } 09576 if (cmd == 't') 09577 cmd = 0; 09578 return cmd; 09579 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11384 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and vm_users_data_provider_get_helper().
11386 { 11387 struct ast_vm_user *user; 11388 11389 AST_LIST_LOCK(&users); 11390 AST_LIST_TRAVERSE(&users, user, list) { 11391 vm_users_data_provider_get_helper(search, data_root, user); 11392 } 11393 AST_LIST_UNLOCK(&users); 11394 11395 return 0; 11396 }
static int vm_users_data_provider_get_helper | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root, | |||
struct ast_vm_user * | user | |||
) | [static] |
Definition at line 11337 of file app_voicemail.c.
References ast_data_add_int(), ast_data_add_node(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::context, inboxcount2(), ast_vm_user::mailbox, and ast_vm_user::zonetag.
Referenced by vm_users_data_provider_get().
11339 { 11340 struct ast_data *data_user, *data_zone; 11341 struct ast_data *data_state; 11342 struct vm_zone *zone = NULL; 11343 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11344 char ext_context[256] = ""; 11345 11346 data_user = ast_data_add_node(data_root, "user"); 11347 if (!data_user) { 11348 return -1; 11349 } 11350 11351 ast_data_add_structure(ast_vm_user, data_user, user); 11352 11353 AST_LIST_LOCK(&zones); 11354 AST_LIST_TRAVERSE(&zones, zone, list) { 11355 if (!strcmp(zone->name, user->zonetag)) { 11356 break; 11357 } 11358 } 11359 AST_LIST_UNLOCK(&zones); 11360 11361 /* state */ 11362 data_state = ast_data_add_node(data_user, "state"); 11363 if (!data_state) { 11364 return -1; 11365 } 11366 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11367 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11368 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11369 ast_data_add_int(data_state, "newmsg", newmsg); 11370 ast_data_add_int(data_state, "oldmsg", oldmsg); 11371 11372 if (zone) { 11373 data_zone = ast_data_add_node(data_user, "zone"); 11374 ast_data_add_structure(vm_zone, data_zone, zone); 11375 } 11376 11377 if (!ast_data_search_match(search, data_user)) { 11378 ast_data_remove_node(data_root, data_user); 11379 } 11380 11381 return 0; 11382 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11023 of file app_voicemail.c.
References ast_copy_string(), ast_goto_if_exists(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_channel::context, ast_vm_user::context, pbx_builtin_setvar_helper(), and vm_authenticate().
Referenced by load_module().
11024 { 11025 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11026 struct ast_vm_user vmus; 11027 char *options = NULL; 11028 int silent = 0, skipuser = 0; 11029 int res = -1; 11030 11031 if (data) { 11032 s = ast_strdupa(data); 11033 user = strsep(&s, ","); 11034 options = strsep(&s, ","); 11035 if (user) { 11036 s = user; 11037 user = strsep(&s, "@"); 11038 context = strsep(&s, ""); 11039 if (!ast_strlen_zero(user)) 11040 skipuser++; 11041 ast_copy_string(mailbox, user, sizeof(mailbox)); 11042 } 11043 } 11044 11045 if (options) { 11046 silent = (strchr(options, 's')) != NULL; 11047 } 11048 11049 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11050 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11051 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11052 ast_play_and_wait(chan, "auth-thankyou"); 11053 res = 0; 11054 } else if (mailbox[0] == '*') { 11055 /* user entered '*' */ 11056 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11057 res = 0; /* prevent hangup */ 11058 } 11059 } 11060 11061 return res; 11062 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12563 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_log(), ast_say_character_str(), ast_strdupa, ast_stream_and_wait(), ast_strlen_zero(), LOG_WARNING, and sayname().
Referenced by load_module().
12564 { 12565 char *context; 12566 char *args_copy; 12567 int res; 12568 12569 if (ast_strlen_zero(data)) { 12570 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n"); 12571 return -1; 12572 } 12573 12574 args_copy = ast_strdupa(data); 12575 if ((context = strchr(args_copy, '@'))) { 12576 *context++ = '\0'; 12577 } else { 12578 context = "default"; 12579 } 12580 12581 if ((res = sayname(chan, args_copy, context) < 0)) { 12582 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12583 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12584 if (!res) { 12585 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12586 } 12587 } 12588 12589 return res; 12590 }
static struct ast_tm* vmu_tm | ( | const struct ast_vm_user * | vmu, | |
struct ast_tm * | tm | |||
) | [static, read] |
fill in *tm for current time according to the proper timezone, if any.
Definition at line 4461 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_strlen_zero(), ast_tvnow(), and ast_vm_user::zonetag.
Referenced by make_email_file(), and sendpage().
04462 { 04463 const struct vm_zone *z = NULL; 04464 struct timeval t = ast_tvnow(); 04465 04466 /* Does this user have a timezone specified? */ 04467 if (!ast_strlen_zero(vmu->zonetag)) { 04468 /* Find the zone in the list */ 04469 AST_LIST_LOCK(&zones); 04470 AST_LIST_TRAVERSE(&zones, z, list) { 04471 if (!strcmp(z->name, vmu->zonetag)) 04472 break; 04473 } 04474 AST_LIST_UNLOCK(&zones); 04475 } 04476 ast_localtime(&t, tm, z ? z->timezone : NULL); 04477 return tm; 04478 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7516 of file app_voicemail.c.
References ast_control_streamfile(), ast_test_suite_event_notify, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, and skipms.
Referenced by advanced_options(), and play_message().
07517 { 07518 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07519 return ast_control_streamfile(chan, file, listen_control_forward_key, listen_control_reverse_key, listen_control_stop_key, listen_control_pause_key, listen_control_restart_key, skipms, NULL); 07520 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7508 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_log(), AST_LOG_WARNING, and ast_stream_and_wait().
Referenced by play_message(), play_message_callerid(), and play_message_duration().
07509 { 07510 int res; 07511 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07512 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07513 return res; 07514 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12530 of file app_voicemail.c.
References ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_destroy(), ast_config_new(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), and LOG_ERROR.
Referenced by vm_change_password().
12530 { 12531 struct ast_config *conf; 12532 struct ast_category *cat; 12533 struct ast_variable *var; 12534 int res = -1; 12535 12536 if (!(conf = ast_config_new())) { 12537 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12538 return res; 12539 } 12540 if (!(cat = ast_category_new("general", "", 1))) { 12541 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12542 ast_config_destroy(conf); 12543 return res; 12544 } 12545 if (!(var = ast_variable_new("password", password, ""))) { 12546 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12547 ast_config_destroy(conf); 12548 ast_category_destroy(cat); 12549 return res; 12550 } 12551 ast_category_append(conf, cat); 12552 ast_variable_append(cat, var); 12553 if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12554 res = 0; 12555 } else { 12556 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12557 } 12558 12559 ast_config_destroy(conf); 12560 return res; 12561 }
char* addesc = "Comedian Mail" [static] |
Definition at line 769 of file app_voicemail.c.
Referenced by adsi_load_vmail().
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 896 of file app_voicemail.c.
Referenced by actual_load_config(), adsi_begin(), and adsi_load_vmail().
unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC" [static] |
Definition at line 897 of file app_voicemail.c.
Referenced by actual_load_config(), and adsi_load_vmail().
int adsiver = 1 [static] |
Definition at line 898 of file app_voicemail.c.
Referenced by actual_load_config(), adsi_begin(), and adsi_load_vmail().
char* app = "VoiceMail" [static] |
Definition at line 772 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* app2 = "VoiceMailMain" [static] |
Definition at line 775 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* app3 = "MailboxExists" [static] |
Definition at line 777 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* app4 = "VMAuthenticate" [static] |
Definition at line 778 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 882 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char charset[32] = "ISO-8859-1" [static] |
Definition at line 894 of file app_voicemail.c.
Referenced by actual_load_config(), ast_str_encode_mime(), make_email_file(), and tds_load_module().
char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static] |
Definition at line 885 of file app_voicemail.c.
Referenced by actual_load_config(), and play_message_callerid().
struct ast_cli_entry cli_voicemail[] [static] |
{ AST_CLI_DEFINE(handle_voicemail_show_users, "List defined voicemail boxes"), AST_CLI_DEFINE(handle_voicemail_show_zones, "List zone message formats"), AST_CLI_DEFINE(handle_voicemail_reload, "Reload voicemail configuration"), }
Definition at line 11262 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 881 of file app_voicemail.c.
Referenced by actual_load_config(), dial_exec_full(), directory_exec(), populate_defaults(), ring_entry(), and wait_for_answer().
char* emailbody = NULL [static] |
Definition at line 888 of file app_voicemail.c.
Referenced by actual_load_config(), make_email_file(), and message_template_parse_emailbody().
char emaildateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 899 of file app_voicemail.c.
Referenced by actual_load_config(), make_email_file(), and prep_email_sub_vars().
char* emailsubject = NULL [static] |
Definition at line 889 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
char exitcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 883 of file app_voicemail.c.
Referenced by actual_load_config(), common_exec(), conf_run(), and populate_defaults().
char ext_pass_check_cmd[128] [static] |
Definition at line 749 of file app_voicemail.c.
Referenced by actual_load_config(), and check_password().
char ext_pass_cmd[128] [static] |
Definition at line 748 of file app_voicemail.c.
Referenced by actual_load_config(), vm_change_password_shell(), vm_newuser(), and vm_options().
char externnotify[160] [static] |
Definition at line 792 of file app_voicemail.c.
Referenced by actual_load_config(), and run_externnotify().
char fromstring[100] [static] |
Definition at line 892 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
struct ast_flags globalflags = {0} [static] |
Definition at line 877 of file app_voicemail.c.
Referenced by actual_load_config(), find_or_create(), find_user(), find_user_realtime(), forward_message(), make_email_file(), populate_defaults(), sendmail(), and vm_execmain().
struct ao2_container* inprocess_container |
Definition at line 921 of file app_voicemail.c.
Referenced by inprocess_count(), load_module(), and unload_module().
char listen_control_forward_key[12] [static] |
Definition at line 850 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_pause_key[12] [static] |
Definition at line 852 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_restart_key[12] [static] |
Definition at line 853 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_reverse_key[12] [static] |
Definition at line 851 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_stop_key[12] [static] |
Definition at line 854 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char locale[20] [static] |
Definition at line 785 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
struct ast_custom_function mailbox_exists_acf [static] |
{ .name = "MAILBOX_EXISTS", .read = acf_mailbox_exists, }
Definition at line 11018 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
const char* const mailbox_folders[] [static] |
Definition at line 1711 of file app_voicemail.c.
Referenced by get_folder_by_name(), and mbox().
char mailcmd[160] [static] |
Definition at line 791 of file app_voicemail.c.
Referenced by actual_load_config(), manager_list_voicemail_users(), sendmail(), and sendpage().
int maxdeletedmsg [static] |
Definition at line 788 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
int maxgreet [static] |
Definition at line 798 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), vm_options(), and vm_tempgreeting().
int maxlogins [static] |
Definition at line 800 of file app_voicemail.c.
Referenced by actual_load_config(), and vm_execmain().
int maxmsg [static] |
Definition at line 787 of file app_voicemail.c.
Referenced by actual_load_config(), copy_message(), and populate_defaults().
int maxsilence [static] |
Definition at line 786 of file app_voicemail.c.
Referenced by actual_load_config(), ast_record_review(), play_record_review(), and vm_forwardoptions().
int minpassword [static] |
Definition at line 801 of file app_voicemail.c.
Referenced by actual_load_config(), and check_password().
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 819 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 845 of file app_voicemail.c.
Referenced by load_module(), mwi_sub_event_cb(), mwi_unsub_event_cb(), and unload_module().
struct ast_event_sub* mwi_unsub_sub [static] |
Subscription to ... MWI event un-subscriptions
Definition at line 821 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
int my_umask [static] |
Definition at line 751 of file app_voicemail.c.
Referenced by add_email_attachment(), leave_voicemail(), load_module(), and vm_mkftemp().
char* pagerbody = NULL [static] |
Definition at line 890 of file app_voicemail.c.
Referenced by actual_load_config(), and sendpage().
char pagerdateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 900 of file app_voicemail.c.
Referenced by actual_load_config(), and sendpage().
char pagerfromstring[100] [static] |
Definition at line 893 of file app_voicemail.c.
Referenced by actual_load_config(), and sendpage().
char* pagersubject = NULL [static] |
Definition at line 891 of file app_voicemail.c.
Referenced by actual_load_config(), and sendpage().
int passwordlocation [static] |
Definition at line 802 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 814 of file app_voicemail.c.
Referenced by mb_poll_thread(), and stop_poll_thread().
unsigned int poll_freq [static] |
Polling frequency
Definition at line 809 of file app_voicemail.c.
Referenced by actual_load_config(), and mb_poll_thread().
unsigned int poll_mailboxes [static] |
Poll mailboxes for changes since there is something external to app_voicemail that may change them.
Definition at line 806 of file app_voicemail.c.
Referenced by actual_load_config().
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 815 of file app_voicemail.c.
Referenced by actual_load_config(), start_poll_thread(), stop_poll_thread(), and unload_module().
unsigned char poll_thread_run [static] |
Definition at line 816 of file app_voicemail.c.
Referenced by mb_poll_thread(), start_poll_thread(), and stop_poll_thread().
int pwdchange = PWDCHANGE_INTERNAL [static] |
Definition at line 755 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
int saydurationminfo [static] |
Definition at line 879 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char* sayname_app = "VMSayName" [static] |
Definition at line 780 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char serveremail[80] [static] |
Definition at line 790 of file app_voicemail.c.
Referenced by actual_load_config(), forward_message(), manager_list_voicemail_users(), and notify_new_message().
int silencethreshold = 128 [static] |
Definition at line 789 of file app_voicemail.c.
Referenced by actual_load_config(), ast_record_review(), play_record_review(), setup_privacy_args(), and vm_forwardoptions().
int skipms [static] |
Definition at line 799 of file app_voicemail.c.
Referenced by actual_load_config(), controlplayback_exec(), handle_controlstreamfile(), and wait_file().
struct ast_smdi_interface* smdi_iface = NULL [static] |
Definition at line 793 of file app_voicemail.c.
Referenced by actual_load_config(), and run_externnotify().
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 767 of file app_voicemail.c.
Referenced by actual_load_config().
struct ast_data_entry vm_data_providers[] [static] |
char vm_invalid_password[80] = "vm-invalid-password" [static] |
Definition at line 862 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
char vm_mismatch[80] = "vm-mismatch" [static] |
Definition at line 861 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
char vm_newpassword[80] = "vm-newpassword" [static] |
Definition at line 858 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
char vm_passchanged[80] = "vm-passchanged" [static] |
Definition at line 859 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
char vm_password[80] = "vm-password" [static] |
Definition at line 857 of file app_voicemail.c.
Referenced by actual_load_config(), and vm_authenticate().
char vm_pls_try_again[80] = "vm-pls-try-again" [static] |
Definition at line 863 of file app_voicemail.c.
Referenced by actual_load_config(), vm_forwardoptions(), vm_newuser(), and vm_options().
char vm_prepend_timeout[80] = "vm-then-pound" [static] |
Definition at line 875 of file app_voicemail.c.
Referenced by actual_load_config(), and vm_forwardoptions().
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 860 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
char VM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 746 of file app_voicemail.c.
Referenced by __has_voicemail(), actual_load_config(), append_mailbox(), forward_message(), invent_message(), leave_voicemail(), load_module(), make_dir(), notify_new_message(), play_message_callerid(), sayname(), vm_change_password(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().
struct ast_data_handler vm_users_data_provider [static] |
{ .version = AST_DATA_HANDLER_VERSION, .get = vm_users_data_provider_get }
Definition at line 11398 of file app_voicemail.c.
char vmfmts[80] [static] |
Definition at line 794 of file app_voicemail.c.
Referenced by actual_load_config(), forward_message(), leave_voicemail(), and vm_execmain().
int vmmaxsecs [static] |
Definition at line 797 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), and populate_defaults().
int vmminsecs [static] |
Definition at line 796 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), and populate_defaults().
double volgain [static] |
Definition at line 795 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char zonetag[80] [static] |
Definition at line 784 of file app_voicemail.c.
Referenced by actual_load_config(), build_peer(), and populate_defaults().