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_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Spanish syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Greek 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_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Italian syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Portuguese 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 11375 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 11402 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 11078 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().
11079 { 11080 struct ast_vm_user svm; 11081 AST_DECLARE_APP_ARGS(arg, 11082 AST_APP_ARG(mbox); 11083 AST_APP_ARG(context); 11084 ); 11085 11086 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11087 11088 if (ast_strlen_zero(arg.mbox)) { 11089 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11090 return -1; 11091 } 11092 11093 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11094 return 0; 11095 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11912 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().
11913 { 11914 struct ast_vm_user *current; 11915 char *cat; 11916 struct ast_variable *var; 11917 const char *val; 11918 char *q, *stringp, *tmp; 11919 int x; 11920 unsigned int tmpadsi[4]; 11921 char secretfn[PATH_MAX] = ""; 11922 11923 #ifdef IMAP_STORAGE 11924 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11925 #endif 11926 /* set audio control prompts */ 11927 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11928 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11929 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11930 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11931 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11932 11933 /* Free all the users structure */ 11934 free_vm_users(); 11935 11936 /* Free all the zones structure */ 11937 free_vm_zones(); 11938 11939 AST_LIST_LOCK(&users); 11940 11941 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11942 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11943 11944 if (cfg) { 11945 /* General settings */ 11946 11947 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11948 val = "default"; 11949 ast_copy_string(userscontext, val, sizeof(userscontext)); 11950 /* Attach voice message to mail message ? */ 11951 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11952 val = "yes"; 11953 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11954 11955 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11956 val = "no"; 11957 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11958 11959 volgain = 0.0; 11960 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11961 sscanf(val, "%30lf", &volgain); 11962 11963 #ifdef ODBC_STORAGE 11964 strcpy(odbc_database, "asterisk"); 11965 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11966 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11967 } 11968 strcpy(odbc_table, "voicemessages"); 11969 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11970 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11971 } 11972 #endif 11973 /* Mail command */ 11974 strcpy(mailcmd, SENDMAIL); 11975 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11976 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11977 11978 maxsilence = 0; 11979 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11980 maxsilence = atoi(val); 11981 if (maxsilence > 0) 11982 maxsilence *= 1000; 11983 } 11984 11985 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11986 maxmsg = MAXMSG; 11987 } else { 11988 maxmsg = atoi(val); 11989 if (maxmsg < 0) { 11990 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11991 maxmsg = MAXMSG; 11992 } else if (maxmsg > MAXMSGLIMIT) { 11993 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11994 maxmsg = MAXMSGLIMIT; 11995 } 11996 } 11997 11998 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11999 maxdeletedmsg = 0; 12000 } else { 12001 if (sscanf(val, "%30d", &x) == 1) 12002 maxdeletedmsg = x; 12003 else if (ast_true(val)) 12004 maxdeletedmsg = MAXMSG; 12005 else 12006 maxdeletedmsg = 0; 12007 12008 if (maxdeletedmsg < 0) { 12009 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 12010 maxdeletedmsg = MAXMSG; 12011 } else if (maxdeletedmsg > MAXMSGLIMIT) { 12012 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 12013 maxdeletedmsg = MAXMSGLIMIT; 12014 } 12015 } 12016 12017 /* Load date format config for voicemail mail */ 12018 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 12019 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 12020 } 12021 12022 /* Load date format config for voicemail pager mail */ 12023 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 12024 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 12025 } 12026 12027 /* External password changing command */ 12028 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 12029 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12030 pwdchange = PWDCHANGE_EXTERNAL; 12031 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 12032 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12033 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 12034 } 12035 12036 /* External password validation command */ 12037 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 12038 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 12039 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 12040 } 12041 12042 #ifdef IMAP_STORAGE 12043 /* IMAP server address */ 12044 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 12045 ast_copy_string(imapserver, val, sizeof(imapserver)); 12046 } else { 12047 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 12048 } 12049 /* IMAP server port */ 12050 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 12051 ast_copy_string(imapport, val, sizeof(imapport)); 12052 } else { 12053 ast_copy_string(imapport, "143", sizeof(imapport)); 12054 } 12055 /* IMAP server flags */ 12056 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 12057 ast_copy_string(imapflags, val, sizeof(imapflags)); 12058 } 12059 /* IMAP server master username */ 12060 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 12061 ast_copy_string(authuser, val, sizeof(authuser)); 12062 } 12063 /* IMAP server master password */ 12064 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 12065 ast_copy_string(authpassword, val, sizeof(authpassword)); 12066 } 12067 /* Expunge on exit */ 12068 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 12069 if (ast_false(val)) 12070 expungeonhangup = 0; 12071 else 12072 expungeonhangup = 1; 12073 } else { 12074 expungeonhangup = 1; 12075 } 12076 /* IMAP voicemail folder */ 12077 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 12078 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12079 } else { 12080 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12081 } 12082 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12083 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12084 } 12085 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12086 imapgreetings = ast_true(val); 12087 } else { 12088 imapgreetings = 0; 12089 } 12090 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12091 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12092 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12093 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12094 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12095 } else { 12096 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12097 } 12098 12099 /* There is some very unorthodox casting done here. This is due 12100 * to the way c-client handles the argument passed in. It expects a 12101 * void pointer and casts the pointer directly to a long without 12102 * first dereferencing it. */ 12103 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12104 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12105 } else { 12106 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12107 } 12108 12109 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12110 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12111 } else { 12112 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12113 } 12114 12115 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12116 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12117 } else { 12118 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12119 } 12120 12121 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12122 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12123 } else { 12124 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12125 } 12126 12127 /* Increment configuration version */ 12128 imapversion++; 12129 #endif 12130 /* External voicemail notify application */ 12131 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12132 ast_copy_string(externnotify, val, sizeof(externnotify)); 12133 ast_debug(1, "found externnotify: %s\n", externnotify); 12134 } else { 12135 externnotify[0] = '\0'; 12136 } 12137 12138 /* SMDI voicemail notification */ 12139 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12140 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12141 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12142 smdi_iface = ast_smdi_interface_find(val); 12143 } else { 12144 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12145 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12146 } 12147 if (!smdi_iface) { 12148 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12149 } 12150 } 12151 12152 /* Silence treshold */ 12153 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12154 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12155 silencethreshold = atoi(val); 12156 12157 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12158 val = ASTERISK_USERNAME; 12159 ast_copy_string(serveremail, val, sizeof(serveremail)); 12160 12161 vmmaxsecs = 0; 12162 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12163 if (sscanf(val, "%30d", &x) == 1) { 12164 vmmaxsecs = x; 12165 } else { 12166 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12167 } 12168 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12169 static int maxmessage_deprecate = 0; 12170 if (maxmessage_deprecate == 0) { 12171 maxmessage_deprecate = 1; 12172 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12173 } 12174 if (sscanf(val, "%30d", &x) == 1) { 12175 vmmaxsecs = x; 12176 } else { 12177 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12178 } 12179 } 12180 12181 vmminsecs = 0; 12182 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12183 if (sscanf(val, "%30d", &x) == 1) { 12184 vmminsecs = x; 12185 if (maxsilence / 1000 >= vmminsecs) { 12186 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12187 } 12188 } else { 12189 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12190 } 12191 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12192 static int maxmessage_deprecate = 0; 12193 if (maxmessage_deprecate == 0) { 12194 maxmessage_deprecate = 1; 12195 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12196 } 12197 if (sscanf(val, "%30d", &x) == 1) { 12198 vmminsecs = x; 12199 if (maxsilence / 1000 >= vmminsecs) { 12200 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12201 } 12202 } else { 12203 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12204 } 12205 } 12206 12207 val = ast_variable_retrieve(cfg, "general", "format"); 12208 if (!val) { 12209 val = "wav"; 12210 } else { 12211 tmp = ast_strdupa(val); 12212 val = ast_format_str_reduce(tmp); 12213 if (!val) { 12214 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12215 val = "wav"; 12216 } 12217 } 12218 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12219 12220 skipms = 3000; 12221 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12222 if (sscanf(val, "%30d", &x) == 1) { 12223 maxgreet = x; 12224 } else { 12225 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12226 } 12227 } 12228 12229 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12230 if (sscanf(val, "%30d", &x) == 1) { 12231 skipms = x; 12232 } else { 12233 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12234 } 12235 } 12236 12237 maxlogins = 3; 12238 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12239 if (sscanf(val, "%30d", &x) == 1) { 12240 maxlogins = x; 12241 } else { 12242 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12243 } 12244 } 12245 12246 minpassword = MINPASSWORD; 12247 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12248 if (sscanf(val, "%30d", &x) == 1) { 12249 minpassword = x; 12250 } else { 12251 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12252 } 12253 } 12254 12255 /* Force new user to record name ? */ 12256 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12257 val = "no"; 12258 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12259 12260 /* Force new user to record greetings ? */ 12261 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12262 val = "no"; 12263 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12264 12265 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12266 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12267 stringp = ast_strdupa(val); 12268 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12269 if (!ast_strlen_zero(stringp)) { 12270 q = strsep(&stringp, ","); 12271 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12272 q++; 12273 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12274 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12275 } else { 12276 cidinternalcontexts[x][0] = '\0'; 12277 } 12278 } 12279 } 12280 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12281 ast_debug(1, "VM Review Option disabled globally\n"); 12282 val = "no"; 12283 } 12284 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12285 12286 /* Temporary greeting reminder */ 12287 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12288 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12289 val = "no"; 12290 } else { 12291 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12292 } 12293 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12294 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12295 ast_debug(1, "VM next message wrap disabled globally\n"); 12296 val = "no"; 12297 } 12298 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12299 12300 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12301 ast_debug(1, "VM Operator break disabled globally\n"); 12302 val = "no"; 12303 } 12304 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12305 12306 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12307 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12308 val = "no"; 12309 } 12310 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12311 12312 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12313 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12314 val = "no"; 12315 } 12316 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12317 12318 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12319 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12320 val = "yes"; 12321 } 12322 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12323 12324 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12325 ast_debug(1, "Move Heard enabled globally\n"); 12326 val = "yes"; 12327 } 12328 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12329 12330 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12331 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12332 val = "no"; 12333 } 12334 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12335 12336 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12337 ast_debug(1, "Duration info before msg enabled globally\n"); 12338 val = "yes"; 12339 } 12340 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12341 12342 saydurationminfo = 2; 12343 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12344 if (sscanf(val, "%30d", &x) == 1) { 12345 saydurationminfo = x; 12346 } else { 12347 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12348 } 12349 } 12350 12351 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12352 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12353 val = "no"; 12354 } 12355 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12356 12357 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12358 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12359 ast_debug(1, "found dialout context: %s\n", dialcontext); 12360 } else { 12361 dialcontext[0] = '\0'; 12362 } 12363 12364 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12365 ast_copy_string(callcontext, val, sizeof(callcontext)); 12366 ast_debug(1, "found callback context: %s\n", callcontext); 12367 } else { 12368 callcontext[0] = '\0'; 12369 } 12370 12371 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12372 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12373 ast_debug(1, "found operator context: %s\n", exitcontext); 12374 } else { 12375 exitcontext[0] = '\0'; 12376 } 12377 12378 /* load password sounds configuration */ 12379 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12380 ast_copy_string(vm_password, val, sizeof(vm_password)); 12381 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12382 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12383 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12384 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12385 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12386 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12387 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12388 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12389 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12390 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12391 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12392 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12393 } 12394 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12395 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12396 } 12397 /* load configurable audio prompts */ 12398 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12399 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12400 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12401 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12402 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12403 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12404 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12405 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12406 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12407 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12408 12409 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12410 val = "no"; 12411 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12412 12413 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12414 val = "voicemail.conf"; 12415 } 12416 if (!(strcmp(val, "spooldir"))) { 12417 passwordlocation = OPT_PWLOC_SPOOLDIR; 12418 } else { 12419 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12420 } 12421 12422 poll_freq = DEFAULT_POLL_FREQ; 12423 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12424 if (sscanf(val, "%30u", &poll_freq) != 1) { 12425 poll_freq = DEFAULT_POLL_FREQ; 12426 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12427 } 12428 } 12429 12430 poll_mailboxes = 0; 12431 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12432 poll_mailboxes = ast_true(val); 12433 12434 memset(fromstring, 0, sizeof(fromstring)); 12435 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12436 strcpy(charset, "ISO-8859-1"); 12437 if (emailbody) { 12438 ast_free(emailbody); 12439 emailbody = NULL; 12440 } 12441 if (emailsubject) { 12442 ast_free(emailsubject); 12443 emailsubject = NULL; 12444 } 12445 if (pagerbody) { 12446 ast_free(pagerbody); 12447 pagerbody = NULL; 12448 } 12449 if (pagersubject) { 12450 ast_free(pagersubject); 12451 pagersubject = NULL; 12452 } 12453 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12454 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12455 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12456 ast_copy_string(fromstring, val, sizeof(fromstring)); 12457 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12458 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12459 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12460 ast_copy_string(charset, val, sizeof(charset)); 12461 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12462 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12463 for (x = 0; x < 4; x++) { 12464 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12465 } 12466 } 12467 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12468 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12469 for (x = 0; x < 4; x++) { 12470 memcpy(&adsisec[x], &tmpadsi[x], 1); 12471 } 12472 } 12473 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12474 if (atoi(val)) { 12475 adsiver = atoi(val); 12476 } 12477 } 12478 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12479 ast_copy_string(zonetag, val, sizeof(zonetag)); 12480 } 12481 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12482 ast_copy_string(locale, val, sizeof(locale)); 12483 } 12484 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12485 emailsubject = ast_strdup(substitute_escapes(val)); 12486 } 12487 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12488 emailbody = ast_strdup(substitute_escapes(val)); 12489 } 12490 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12491 pagersubject = ast_strdup(substitute_escapes(val)); 12492 } 12493 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12494 pagerbody = ast_strdup(substitute_escapes(val)); 12495 } 12496 12497 /* load mailboxes from users.conf */ 12498 if (ucfg) { 12499 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12500 if (!strcasecmp(cat, "general")) { 12501 continue; 12502 } 12503 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12504 continue; 12505 if ((current = find_or_create(userscontext, cat))) { 12506 populate_defaults(current); 12507 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12508 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12509 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12510 current->passwordlocation = OPT_PWLOC_USERSCONF; 12511 } 12512 12513 switch (current->passwordlocation) { 12514 case OPT_PWLOC_SPOOLDIR: 12515 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12516 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12517 } 12518 } 12519 } 12520 } 12521 12522 /* load mailboxes from voicemail.conf */ 12523 cat = ast_category_browse(cfg, NULL); 12524 while (cat) { 12525 if (strcasecmp(cat, "general")) { 12526 var = ast_variable_browse(cfg, cat); 12527 if (strcasecmp(cat, "zonemessages")) { 12528 /* Process mailboxes in this context */ 12529 while (var) { 12530 append_mailbox(cat, var->name, var->value); 12531 var = var->next; 12532 } 12533 } else { 12534 /* Timezones in this context */ 12535 while (var) { 12536 struct vm_zone *z; 12537 if ((z = ast_malloc(sizeof(*z)))) { 12538 char *msg_format, *tzone; 12539 msg_format = ast_strdupa(var->value); 12540 tzone = strsep(&msg_format, "|,"); 12541 if (msg_format) { 12542 ast_copy_string(z->name, var->name, sizeof(z->name)); 12543 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12544 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12545 AST_LIST_LOCK(&zones); 12546 AST_LIST_INSERT_HEAD(&zones, z, list); 12547 AST_LIST_UNLOCK(&zones); 12548 } else { 12549 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12550 ast_free(z); 12551 } 12552 } else { 12553 AST_LIST_UNLOCK(&users); 12554 return -1; 12555 } 12556 var = var->next; 12557 } 12558 } 12559 } 12560 cat = ast_category_browse(cfg, cat); 12561 } 12562 12563 AST_LIST_UNLOCK(&users); 12564 12565 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12566 start_poll_thread(); 12567 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12568 stop_poll_thread();; 12569 12570 return 0; 12571 } else { 12572 AST_LIST_UNLOCK(&users); 12573 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12574 return 0; 12575 } 12576 }
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 13284 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().
13285 { 13286 int res = 0; 13287 char filename[PATH_MAX]; 13288 struct ast_config *msg_cfg = NULL; 13289 const char *origtime, *context; 13290 char *name, *num; 13291 int retries = 0; 13292 char *cid; 13293 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13294 13295 vms->starting = 0; 13296 13297 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13298 13299 /* Retrieve info from VM attribute file */ 13300 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13301 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13302 msg_cfg = ast_config_load(filename, config_flags); 13303 DISPOSE(vms->curdir, vms->curmsg); 13304 if (!valid_config(msg_cfg)) { 13305 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13306 return 0; 13307 } 13308 13309 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13310 ast_config_destroy(msg_cfg); 13311 return 0; 13312 } 13313 13314 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13315 13316 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13317 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13318 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13319 switch (option) { 13320 case 3: /* Play message envelope */ 13321 if (!res) 13322 res = play_message_datetime(chan, vmu, origtime, filename); 13323 if (!res) 13324 res = play_message_callerid(chan, vms, cid, context, 0); 13325 13326 res = 't'; 13327 break; 13328 13329 case 2: /* Call back */ 13330 13331 if (ast_strlen_zero(cid)) 13332 break; 13333 13334 ast_callerid_parse(cid, &name, &num); 13335 while ((res > -1) && (res != 't')) { 13336 switch (res) { 13337 case '1': 13338 if (num) { 13339 /* Dial the CID number */ 13340 res = dialout(chan, vmu, num, vmu->callback); 13341 if (res) { 13342 ast_config_destroy(msg_cfg); 13343 return 9; 13344 } 13345 } else { 13346 res = '2'; 13347 } 13348 break; 13349 13350 case '2': 13351 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13352 if (!ast_strlen_zero(vmu->dialout)) { 13353 res = dialout(chan, vmu, NULL, vmu->dialout); 13354 if (res) { 13355 ast_config_destroy(msg_cfg); 13356 return 9; 13357 } 13358 } else { 13359 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13360 res = ast_play_and_wait(chan, "vm-sorry"); 13361 } 13362 ast_config_destroy(msg_cfg); 13363 return res; 13364 case '*': 13365 res = 't'; 13366 break; 13367 case '3': 13368 case '4': 13369 case '5': 13370 case '6': 13371 case '7': 13372 case '8': 13373 case '9': 13374 case '0': 13375 13376 res = ast_play_and_wait(chan, "vm-sorry"); 13377 retries++; 13378 break; 13379 default: 13380 if (num) { 13381 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13382 res = ast_play_and_wait(chan, "vm-num-i-have"); 13383 if (!res) 13384 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13385 if (!res) 13386 res = ast_play_and_wait(chan, "vm-tocallnum"); 13387 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13388 if (!ast_strlen_zero(vmu->dialout)) { 13389 if (!res) 13390 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13391 } 13392 } else { 13393 res = ast_play_and_wait(chan, "vm-nonumber"); 13394 if (!ast_strlen_zero(vmu->dialout)) { 13395 if (!res) 13396 res = ast_play_and_wait(chan, "vm-toenternumber"); 13397 } 13398 } 13399 if (!res) { 13400 res = ast_play_and_wait(chan, "vm-star-cancel"); 13401 } 13402 if (!res) { 13403 res = ast_waitfordigit(chan, 6000); 13404 } 13405 if (!res) { 13406 retries++; 13407 if (retries > 3) { 13408 res = 't'; 13409 } 13410 } 13411 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13412 break; 13413 13414 } 13415 if (res == 't') 13416 res = 0; 13417 else if (res == '*') 13418 res = -1; 13419 } 13420 break; 13421 13422 case 1: /* Reply */ 13423 /* Send reply directly to sender */ 13424 if (ast_strlen_zero(cid)) 13425 break; 13426 13427 ast_callerid_parse(cid, &name, &num); 13428 if (!num) { 13429 ast_verb(3, "No CID number available, no reply sent\n"); 13430 if (!res) 13431 res = ast_play_and_wait(chan, "vm-nonumber"); 13432 ast_config_destroy(msg_cfg); 13433 return res; 13434 } else { 13435 struct ast_vm_user vmu2; 13436 if (find_user(&vmu2, vmu->context, num)) { 13437 struct leave_vm_options leave_options; 13438 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13439 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13440 13441 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13442 13443 memset(&leave_options, 0, sizeof(leave_options)); 13444 leave_options.record_gain = record_gain; 13445 res = leave_voicemail(chan, mailbox, &leave_options); 13446 if (!res) 13447 res = 't'; 13448 ast_config_destroy(msg_cfg); 13449 return res; 13450 } else { 13451 /* Sender has no mailbox, can't reply */ 13452 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13453 ast_play_and_wait(chan, "vm-nobox"); 13454 res = 't'; 13455 ast_config_destroy(msg_cfg); 13456 return res; 13457 } 13458 } 13459 res = 0; 13460 13461 break; 13462 } 13463 13464 ast_config_destroy(msg_cfg); 13465 13466 #ifndef IMAP_STORAGE 13467 if (!res) { 13468 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13469 vms->heard[msg] = 1; 13470 res = wait_file(chan, vms, vms->fn); 13471 } 13472 #endif 13473 return res; 13474 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10805 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().
10806 { 10807 /* Assumes lock is already held */ 10808 char *tmp; 10809 char *stringp; 10810 char *s; 10811 struct ast_vm_user *vmu; 10812 char *mailbox_full; 10813 int new = 0, old = 0, urgent = 0; 10814 char secretfn[PATH_MAX] = ""; 10815 10816 tmp = ast_strdupa(data); 10817 10818 if (!(vmu = find_or_create(context, box))) 10819 return -1; 10820 10821 populate_defaults(vmu); 10822 10823 stringp = tmp; 10824 if ((s = strsep(&stringp, ","))) { 10825 if (!ast_strlen_zero(s) && s[0] == '*') { 10826 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10827 "\n\tmust be reset in voicemail.conf.\n", box); 10828 } 10829 /* assign password regardless of validity to prevent NULL password from being assigned */ 10830 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10831 } 10832 if (stringp && (s = strsep(&stringp, ","))) { 10833 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10834 } 10835 if (stringp && (s = strsep(&stringp, ","))) { 10836 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10837 } 10838 if (stringp && (s = strsep(&stringp, ","))) { 10839 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10840 } 10841 if (stringp && (s = strsep(&stringp, ","))) { 10842 apply_options(vmu, s); 10843 } 10844 10845 switch (vmu->passwordlocation) { 10846 case OPT_PWLOC_SPOOLDIR: 10847 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10848 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10849 } 10850 10851 mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1); 10852 strcpy(mailbox_full, box); 10853 strcat(mailbox_full, "@"); 10854 strcat(mailbox_full, context); 10855 10856 inboxcount2(mailbox_full, &urgent, &new, &old); 10857 queue_mwi_event(mailbox_full, urgent, new, old); 10858 10859 return 0; 10860 }
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 10862 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.
10863 { 10864 int res = 0; 10865 struct ast_vm_user *vmu; 10866 /* language parameter seems to only be used for display in manager action */ 10867 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10868 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10869 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10870 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10871 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10872 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10873 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10874 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10875 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10876 #ifdef IMAP_STORAGE 10877 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10878 "imapfolder=INBOX|imapvmshareid=6000"; 10879 #endif 10880 10881 switch (cmd) { 10882 case TEST_INIT: 10883 info->name = "vmuser"; 10884 info->category = "/apps/app_voicemail/"; 10885 info->summary = "Vmuser unit test"; 10886 info->description = 10887 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10888 return AST_TEST_NOT_RUN; 10889 case TEST_EXECUTE: 10890 break; 10891 } 10892 10893 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10894 return AST_TEST_NOT_RUN; 10895 } 10896 populate_defaults(vmu); 10897 ast_set_flag(vmu, VM_ALLOCED); 10898 10899 apply_options(vmu, options_string); 10900 10901 if (!ast_test_flag(vmu, VM_ATTACH)) { 10902 ast_test_status_update(test, "Parse failure for attach option\n"); 10903 res = 1; 10904 } 10905 if (strcasecmp(vmu->attachfmt, "wav49")) { 10906 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10907 res = 1; 10908 } 10909 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10910 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10911 res = 1; 10912 } 10913 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10914 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10915 res = 1; 10916 } 10917 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10918 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10919 res = 1; 10920 } 10921 if (strcasecmp(vmu->zonetag, "central")) { 10922 ast_test_status_update(test, "Parse failure for tz option\n"); 10923 res = 1; 10924 } 10925 if (!ast_test_flag(vmu, VM_DELETE)) { 10926 ast_test_status_update(test, "Parse failure for delete option\n"); 10927 res = 1; 10928 } 10929 if (!ast_test_flag(vmu, VM_SAYCID)) { 10930 ast_test_status_update(test, "Parse failure for saycid option\n"); 10931 res = 1; 10932 } 10933 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10934 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10935 res = 1; 10936 } 10937 if (!ast_test_flag(vmu, VM_REVIEW)) { 10938 ast_test_status_update(test, "Parse failure for review option\n"); 10939 res = 1; 10940 } 10941 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10942 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10943 res = 1; 10944 } 10945 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10946 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10947 res = 1; 10948 } 10949 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10950 ast_test_status_update(test, "Parse failure for operator option\n"); 10951 res = 1; 10952 } 10953 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10954 ast_test_status_update(test, "Parse failure for envelope option\n"); 10955 res = 1; 10956 } 10957 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10958 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10959 res = 1; 10960 } 10961 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10962 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10963 res = 1; 10964 } 10965 if (vmu->saydurationm != 5) { 10966 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10967 res = 1; 10968 } 10969 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10970 ast_test_status_update(test, "Parse failure for forcename option\n"); 10971 res = 1; 10972 } 10973 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10974 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10975 res = 1; 10976 } 10977 if (strcasecmp(vmu->callback, "somecontext")) { 10978 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10979 res = 1; 10980 } 10981 if (strcasecmp(vmu->dialout, "somecontext2")) { 10982 ast_test_status_update(test, "Parse failure for dialout option\n"); 10983 res = 1; 10984 } 10985 if (strcasecmp(vmu->exit, "somecontext3")) { 10986 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10987 res = 1; 10988 } 10989 if (vmu->minsecs != 10) { 10990 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10991 res = 1; 10992 } 10993 if (vmu->maxsecs != 100) { 10994 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10995 res = 1; 10996 } 10997 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10998 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10999 res = 1; 11000 } 11001 if (vmu->maxdeletedmsg != 50) { 11002 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 11003 res = 1; 11004 } 11005 if (vmu->volgain != 1.3) { 11006 ast_test_status_update(test, "Parse failure for volgain option\n"); 11007 res = 1; 11008 } 11009 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 11010 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 11011 res = 1; 11012 } 11013 #ifdef IMAP_STORAGE 11014 apply_options(vmu, option_string2); 11015 11016 if (strcasecmp(vmu->imapuser, "imapuser")) { 11017 ast_test_status_update(test, "Parse failure for imapuser option\n"); 11018 res = 1; 11019 } 11020 if (strcasecmp(vmu->imappassword, "imappasswd")) { 11021 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 11022 res = 1; 11023 } 11024 if (strcasecmp(vmu->imapfolder, "INBOX")) { 11025 ast_test_status_update(test, "Parse failure for imapfolder option\n"); 11026 res = 1; 11027 } 11028 if (strcasecmp(vmu->imapvmshareid, "6000")) { 11029 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 11030 res = 1; 11031 } 11032 #endif 11033 11034 free_user(vmu); 11035 return res ? AST_TEST_FAIL : AST_TEST_PASS; 11036 }
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 11182 of file app_voicemail.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
11183 { 11184 int which = 0; 11185 int wordlen; 11186 struct ast_vm_user *vmu; 11187 const char *context = ""; 11188 11189 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11190 if (pos > 4) 11191 return NULL; 11192 if (pos == 3) 11193 return (state == 0) ? ast_strdup("for") : NULL; 11194 wordlen = strlen(word); 11195 AST_LIST_TRAVERSE(&users, vmu, list) { 11196 if (!strncasecmp(word, vmu->context, wordlen)) { 11197 if (context && strcmp(context, vmu->context) && ++which > state) 11198 return ast_strdup(vmu->context); 11199 /* ignore repeated contexts ? */ 11200 context = vmu->context; 11201 } 11202 } 11203 return NULL; 11204 }
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 13211 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().
13212 { 13213 int cmd = 0; 13214 char destination[80] = ""; 13215 int retries = 0; 13216 13217 if (!num) { 13218 ast_verb(3, "Destination number will be entered manually\n"); 13219 while (retries < 3 && cmd != 't') { 13220 destination[1] = '\0'; 13221 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13222 if (!cmd) 13223 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13224 if (!cmd) 13225 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13226 if (!cmd) { 13227 cmd = ast_waitfordigit(chan, 6000); 13228 if (cmd) 13229 destination[0] = cmd; 13230 } 13231 if (!cmd) { 13232 retries++; 13233 } else { 13234 13235 if (cmd < 0) 13236 return 0; 13237 if (cmd == '*') { 13238 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13239 return 0; 13240 } 13241 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13242 retries++; 13243 else 13244 cmd = 't'; 13245 } 13246 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13247 } 13248 if (retries >= 3) { 13249 return 0; 13250 } 13251 13252 } else { 13253 if (option_verbose > 2) 13254 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13255 ast_copy_string(destination, num, sizeof(destination)); 13256 } 13257 13258 if (!ast_strlen_zero(destination)) { 13259 if (destination[strlen(destination) -1 ] == '*') 13260 return 0; 13261 if (option_verbose > 2) 13262 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13263 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13264 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13265 chan->priority = 0; 13266 return 9; 13267 } 13268 return 0; 13269 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static, read] |
Definition at line 10765 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().
10766 { 10767 struct ast_vm_user *vmu; 10768 10769 if (!ast_strlen_zero(box) && box[0] == '*') { 10770 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10771 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10772 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10773 "\n\tand will be ignored.\n", box, context); 10774 return NULL; 10775 } 10776 10777 AST_LIST_TRAVERSE(&users, vmu, list) { 10778 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10779 if (strcasecmp(vmu->context, context)) { 10780 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10781 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10782 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10783 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10784 } 10785 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10786 return NULL; 10787 } 10788 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10789 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10790 return NULL; 10791 } 10792 } 10793 10794 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10795 return NULL; 10796 10797 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10798 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10799 10800 AST_LIST_INSERT_TAIL(&users, vmu, list); 10801 10802 return vmu; 10803 }
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 11794 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().
11795 { 11796 struct ast_vm_user *current; 11797 AST_LIST_LOCK(&users); 11798 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11799 ast_set_flag(current, VM_ALLOCED); 11800 free_user(current); 11801 } 11802 AST_LIST_UNLOCK(&users); 11803 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11806 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().
11807 { 11808 struct vm_zone *zcur; 11809 AST_LIST_LOCK(&zones); 11810 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11811 free_zone(zcur); 11812 AST_LIST_UNLOCK(&zones); 11813 }
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 11564 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().
11565 { 11566 unsigned int len; 11567 struct mwi_sub *mwi_sub; 11568 struct mwi_sub_task *p = datap; 11569 11570 len = sizeof(*mwi_sub); 11571 if (!ast_strlen_zero(p->mailbox)) 11572 len += strlen(p->mailbox); 11573 11574 if (!ast_strlen_zero(p->context)) 11575 len += strlen(p->context) + 1; /* Allow for seperator */ 11576 11577 if (!(mwi_sub = ast_calloc(1, len))) 11578 return -1; 11579 11580 mwi_sub->uniqueid = p->uniqueid; 11581 if (!ast_strlen_zero(p->mailbox)) 11582 strcpy(mwi_sub->mailbox, p->mailbox); 11583 11584 if (!ast_strlen_zero(p->context)) { 11585 strcat(mwi_sub->mailbox, "@"); 11586 strcat(mwi_sub->mailbox, p->context); 11587 } 11588 11589 AST_RWLIST_WRLOCK(&mwi_subs); 11590 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11591 AST_RWLIST_UNLOCK(&mwi_subs); 11592 ast_free((void *) p->mailbox); 11593 ast_free((void *) p->context); 11594 ast_free(p); 11595 poll_subscribed_mailbox(mwi_sub); 11596 return 0; 11597 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11542 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().
11543 { 11544 struct mwi_sub *mwi_sub; 11545 uint32_t *uniqueid = datap; 11546 11547 AST_RWLIST_WRLOCK(&mwi_subs); 11548 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11549 if (mwi_sub->uniqueid == *uniqueid) { 11550 AST_LIST_REMOVE_CURRENT(entry); 11551 break; 11552 } 11553 } 11554 AST_RWLIST_TRAVERSE_SAFE_END 11555 AST_RWLIST_UNLOCK(&mwi_subs); 11556 11557 if (mwi_sub) 11558 mwi_sub_destroy(mwi_sub); 11559 11560 ast_free(uniqueid); 11561 return 0; 11562 }
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 11319 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.
11320 { 11321 switch (cmd) { 11322 case CLI_INIT: 11323 e->command = "voicemail reload"; 11324 e->usage = 11325 "Usage: voicemail reload\n" 11326 " Reload voicemail configuration\n"; 11327 return NULL; 11328 case CLI_GENERATE: 11329 return NULL; 11330 } 11331 11332 if (a->argc != 2) 11333 return CLI_SHOWUSAGE; 11334 11335 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11336 load_config(1); 11337 11338 return CLI_SUCCESS; 11339 }
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 11207 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.
11208 { 11209 struct ast_vm_user *vmu; 11210 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11211 const char *context = NULL; 11212 int users_counter = 0; 11213 11214 switch (cmd) { 11215 case CLI_INIT: 11216 e->command = "voicemail show users"; 11217 e->usage = 11218 "Usage: voicemail show users [for <context>]\n" 11219 " Lists all mailboxes currently set up\n"; 11220 return NULL; 11221 case CLI_GENERATE: 11222 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11223 } 11224 11225 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11226 return CLI_SHOWUSAGE; 11227 if (a->argc == 5) { 11228 if (strcmp(a->argv[3],"for")) 11229 return CLI_SHOWUSAGE; 11230 context = a->argv[4]; 11231 } 11232 11233 if (ast_check_realtime("voicemail")) { 11234 if (!context) { 11235 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11236 return CLI_SHOWUSAGE; 11237 } 11238 return show_users_realtime(a->fd, context); 11239 } 11240 11241 AST_LIST_LOCK(&users); 11242 if (AST_LIST_EMPTY(&users)) { 11243 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11244 AST_LIST_UNLOCK(&users); 11245 return CLI_FAILURE; 11246 } 11247 if (!context) { 11248 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11249 } else { 11250 int count = 0; 11251 AST_LIST_TRAVERSE(&users, vmu, list) { 11252 if (!strcmp(context, vmu->context)) { 11253 count++; 11254 break; 11255 } 11256 } 11257 if (count) { 11258 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11259 } else { 11260 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11261 AST_LIST_UNLOCK(&users); 11262 return CLI_FAILURE; 11263 } 11264 } 11265 AST_LIST_TRAVERSE(&users, vmu, list) { 11266 int newmsgs = 0, oldmsgs = 0; 11267 char count[12], tmp[256] = ""; 11268 11269 if (!context || !strcmp(context, vmu->context)) { 11270 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11271 inboxcount(tmp, &newmsgs, &oldmsgs); 11272 snprintf(count, sizeof(count), "%d", newmsgs); 11273 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11274 users_counter++; 11275 } 11276 } 11277 AST_LIST_UNLOCK(&users); 11278 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11279 return CLI_SUCCESS; 11280 }
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 11283 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.
11284 { 11285 struct vm_zone *zone; 11286 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11287 char *res = CLI_SUCCESS; 11288 11289 switch (cmd) { 11290 case CLI_INIT: 11291 e->command = "voicemail show zones"; 11292 e->usage = 11293 "Usage: voicemail show zones\n" 11294 " Lists zone message formats\n"; 11295 return NULL; 11296 case CLI_GENERATE: 11297 return NULL; 11298 } 11299 11300 if (a->argc != 3) 11301 return CLI_SHOWUSAGE; 11302 11303 AST_LIST_LOCK(&zones); 11304 if (!AST_LIST_EMPTY(&zones)) { 11305 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11306 AST_LIST_TRAVERSE(&zones, zone, list) { 11307 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11308 } 11309 } else { 11310 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11311 res = CLI_FAILURE; 11312 } 11313 AST_LIST_UNLOCK(&zones); 11314 11315 return res; 11316 }
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 11862 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().
11863 { 11864 struct ast_config *cfg, *ucfg; 11865 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11866 int res; 11867 11868 ast_unload_realtime("voicemail"); 11869 ast_unload_realtime("voicemail_data"); 11870 11871 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11872 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11873 return 0; 11874 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11875 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11876 ucfg = NULL; 11877 } 11878 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11879 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11880 ast_config_destroy(ucfg); 11881 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11882 return 0; 11883 } 11884 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11885 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11886 return 0; 11887 } else { 11888 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11889 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11890 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11891 ucfg = NULL; 11892 } 11893 } 11894 11895 res = actual_load_config(reload, cfg, ucfg); 11896 11897 ast_config_destroy(cfg); 11898 ast_config_destroy(ucfg); 11899 11900 return res; 11901 }
static int load_module | ( | void | ) | [static] |
Definition at line 13163 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().
13164 { 13165 int res; 13166 my_umask = umask(0); 13167 umask(my_umask); 13168 13169 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13170 return AST_MODULE_LOAD_DECLINE; 13171 } 13172 13173 /* compute the location of the voicemail spool directory */ 13174 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13175 13176 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13177 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13178 } 13179 13180 if ((res = load_config(0))) 13181 return res; 13182 13183 res = ast_register_application_xml(app, vm_exec); 13184 res |= ast_register_application_xml(app2, vm_execmain); 13185 res |= ast_register_application_xml(app3, vm_box_exists); 13186 res |= ast_register_application_xml(app4, vmauthenticate); 13187 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13188 res |= ast_custom_function_register(&mailbox_exists_acf); 13189 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13190 #ifdef TEST_FRAMEWORK 13191 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13192 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13193 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13194 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13195 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13196 #endif 13197 13198 if (res) 13199 return res; 13200 13201 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13202 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13203 13204 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13205 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13206 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13207 13208 return res; 13209 }
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 11693 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().
11694 { 11695 struct ast_vm_user *vmu = NULL; 11696 const char *id = astman_get_header(m, "ActionID"); 11697 char actionid[128] = ""; 11698 11699 if (!ast_strlen_zero(id)) 11700 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11701 11702 AST_LIST_LOCK(&users); 11703 11704 if (AST_LIST_EMPTY(&users)) { 11705 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11706 AST_LIST_UNLOCK(&users); 11707 return RESULT_SUCCESS; 11708 } 11709 11710 astman_send_ack(s, m, "Voicemail user list will follow"); 11711 11712 AST_LIST_TRAVERSE(&users, vmu, list) { 11713 char dirname[256]; 11714 11715 #ifdef IMAP_STORAGE 11716 int new, old; 11717 inboxcount(vmu->mailbox, &new, &old); 11718 #endif 11719 11720 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11721 astman_append(s, 11722 "%s" 11723 "Event: VoicemailUserEntry\r\n" 11724 "VMContext: %s\r\n" 11725 "VoiceMailbox: %s\r\n" 11726 "Fullname: %s\r\n" 11727 "Email: %s\r\n" 11728 "Pager: %s\r\n" 11729 "ServerEmail: %s\r\n" 11730 "MailCommand: %s\r\n" 11731 "Language: %s\r\n" 11732 "TimeZone: %s\r\n" 11733 "Callback: %s\r\n" 11734 "Dialout: %s\r\n" 11735 "UniqueID: %s\r\n" 11736 "ExitContext: %s\r\n" 11737 "SayDurationMinimum: %d\r\n" 11738 "SayEnvelope: %s\r\n" 11739 "SayCID: %s\r\n" 11740 "AttachMessage: %s\r\n" 11741 "AttachmentFormat: %s\r\n" 11742 "DeleteMessage: %s\r\n" 11743 "VolumeGain: %.2f\r\n" 11744 "CanReview: %s\r\n" 11745 "CallOperator: %s\r\n" 11746 "MaxMessageCount: %d\r\n" 11747 "MaxMessageLength: %d\r\n" 11748 "NewMessageCount: %d\r\n" 11749 #ifdef IMAP_STORAGE 11750 "OldMessageCount: %d\r\n" 11751 "IMAPUser: %s\r\n" 11752 #endif 11753 "\r\n", 11754 actionid, 11755 vmu->context, 11756 vmu->mailbox, 11757 vmu->fullname, 11758 vmu->email, 11759 vmu->pager, 11760 ast_strlen_zero(vmu->serveremail) ? serveremail : vmu->serveremail, 11761 mailcmd, 11762 vmu->language, 11763 vmu->zonetag, 11764 vmu->callback, 11765 vmu->dialout, 11766 vmu->uniqueid, 11767 vmu->exit, 11768 vmu->saydurationm, 11769 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11770 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11771 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11772 vmu->attachfmt, 11773 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11774 vmu->volgain, 11775 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11776 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11777 vmu->maxmsg, 11778 vmu->maxsecs, 11779 #ifdef IMAP_STORAGE 11780 new, old, vmu->imapuser 11781 #else 11782 count_messages(vmu, dirname) 11783 #endif 11784 ); 11785 } 11786 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11787 11788 AST_LIST_UNLOCK(&users); 11789 11790 return RESULT_SUCCESS; 11791 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11514 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().
11515 { 11516 while (poll_thread_run) { 11517 struct timespec ts = { 0, }; 11518 struct timeval wait; 11519 11520 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11521 ts.tv_sec = wait.tv_sec; 11522 ts.tv_nsec = wait.tv_usec * 1000; 11523 11524 ast_mutex_lock(&poll_lock); 11525 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11526 ast_mutex_unlock(&poll_lock); 11527 11528 if (!poll_thread_run) 11529 break; 11530 11531 poll_subscribed_mailboxes(); 11532 } 11533 11534 return NULL; 11535 }
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 11537 of file app_voicemail.c.
References ast_free.
Referenced by handle_unsubscribe().
11538 { 11539 ast_free(mwi_sub); 11540 }
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11625 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().
11626 { 11627 struct mwi_sub_task *mwist; 11628 11629 if (ast_event_get_type(event) != AST_EVENT_SUB) 11630 return; 11631 11632 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11633 return; 11634 11635 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11636 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11637 return; 11638 } 11639 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11640 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11641 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11642 11643 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11644 ast_free(mwist); 11645 } 11646 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11599 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().
11600 { 11601 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11602 11603 if (!uniqueid) { 11604 ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); 11605 return; 11606 } 11607 11608 if (ast_event_get_type(event) != AST_EVENT_UNSUB) { 11609 ast_free(uniqueid); 11610 return; 11611 } 11612 11613 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { 11614 ast_free(uniqueid); 11615 return; 11616 } 11617 11618 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11619 *uniqueid = u; 11620 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11621 ast_free(uniqueid); 11622 } 11623 }
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_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), 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 13476 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().
13479 { 13480 /* Record message & let caller review or re-record it, or set options if applicable */ 13481 int res = 0; 13482 int cmd = 0; 13483 int max_attempts = 3; 13484 int attempts = 0; 13485 int recorded = 0; 13486 int msg_exists = 0; 13487 signed char zero_gain = 0; 13488 char tempfile[PATH_MAX]; 13489 char *acceptdtmf = "#"; 13490 char *canceldtmf = ""; 13491 int canceleddtmf = 0; 13492 13493 /* Note that urgent and private are for flagging messages as such in the future */ 13494 13495 /* barf if no pointer passed to store duration in */ 13496 if (duration == NULL) { 13497 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13498 return -1; 13499 } 13500 13501 if (!outsidecaller) 13502 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13503 else 13504 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13505 13506 cmd = '3'; /* Want to start by recording */ 13507 13508 while ((cmd >= 0) && (cmd != 't')) { 13509 switch (cmd) { 13510 case '1': 13511 if (!msg_exists) { 13512 /* In this case, 1 is to record a message */ 13513 cmd = '3'; 13514 break; 13515 } else { 13516 /* Otherwise 1 is to save the existing message */ 13517 ast_verb(3, "Saving message as is\n"); 13518 if (!outsidecaller) 13519 ast_filerename(tempfile, recordfile, NULL); 13520 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13521 if (!outsidecaller) { 13522 /* Saves to IMAP server only if imapgreeting=yes */ 13523 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13524 DISPOSE(recordfile, -1); 13525 } 13526 cmd = 't'; 13527 return res; 13528 } 13529 case '2': 13530 /* Review */ 13531 ast_verb(3, "Reviewing the message\n"); 13532 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13533 break; 13534 case '3': 13535 msg_exists = 0; 13536 /* Record */ 13537 if (recorded == 1) 13538 ast_verb(3, "Re-recording the message\n"); 13539 else 13540 ast_verb(3, "Recording the message\n"); 13541 13542 if (recorded && outsidecaller) { 13543 cmd = ast_play_and_wait(chan, INTRO); 13544 cmd = ast_play_and_wait(chan, "beep"); 13545 } 13546 recorded = 1; 13547 /* 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 */ 13548 if (record_gain) 13549 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13550 if (ast_test_flag(vmu, VM_OPERATOR)) 13551 canceldtmf = "0"; 13552 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13553 if (strchr(canceldtmf, cmd)) { 13554 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13555 canceleddtmf = 1; 13556 } 13557 if (record_gain) 13558 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13559 if (cmd == -1) { 13560 /* User has hung up, no options to give */ 13561 if (!outsidecaller) { 13562 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13563 ast_filedelete(tempfile, NULL); 13564 } 13565 return cmd; 13566 } 13567 if (cmd == '0') { 13568 break; 13569 } else if (cmd == '*') { 13570 break; 13571 #if 0 13572 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13573 /* Message is too short */ 13574 ast_verb(3, "Message too short\n"); 13575 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13576 cmd = ast_filedelete(tempfile, NULL); 13577 break; 13578 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13579 /* Message is all silence */ 13580 ast_verb(3, "Nothing recorded\n"); 13581 cmd = ast_filedelete(tempfile, NULL); 13582 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13583 if (!cmd) 13584 cmd = ast_play_and_wait(chan, "vm-speakup"); 13585 break; 13586 #endif 13587 } else { 13588 /* If all is well, a message exists */ 13589 msg_exists = 1; 13590 cmd = 0; 13591 } 13592 break; 13593 case '4': 13594 if (outsidecaller) { /* only mark vm messages */ 13595 /* Mark Urgent */ 13596 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13597 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13598 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13599 strcpy(flag, "Urgent"); 13600 } else if (flag) { 13601 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13602 res = ast_play_and_wait(chan, "vm-marked-nonurgent"); 13603 strcpy(flag, ""); 13604 } else { 13605 ast_play_and_wait(chan, "vm-sorry"); 13606 } 13607 cmd = 0; 13608 } else { 13609 cmd = ast_play_and_wait(chan, "vm-sorry"); 13610 } 13611 break; 13612 case '5': 13613 case '6': 13614 case '7': 13615 case '8': 13616 case '9': 13617 case '*': 13618 case '#': 13619 cmd = ast_play_and_wait(chan, "vm-sorry"); 13620 break; 13621 #if 0 13622 /* XXX Commented out for the moment because of the dangers of deleting 13623 a message while recording (can put the message numbers out of sync) */ 13624 case '*': 13625 /* Cancel recording, delete message, offer to take another message*/ 13626 cmd = ast_play_and_wait(chan, "vm-deleted"); 13627 cmd = ast_filedelete(tempfile, NULL); 13628 if (outsidecaller) { 13629 res = vm_exec(chan, NULL); 13630 return res; 13631 } 13632 else 13633 return 1; 13634 #endif 13635 case '0': 13636 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13637 cmd = ast_play_and_wait(chan, "vm-sorry"); 13638 break; 13639 } 13640 if (msg_exists || recorded) { 13641 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13642 if (!cmd) 13643 cmd = ast_waitfordigit(chan, 3000); 13644 if (cmd == '1') { 13645 ast_filerename(tempfile, recordfile, NULL); 13646 ast_play_and_wait(chan, "vm-msgsaved"); 13647 cmd = '0'; 13648 } else if (cmd == '4') { 13649 if (flag) { 13650 ast_play_and_wait(chan, "vm-marked-urgent"); 13651 strcpy(flag, "Urgent"); 13652 } 13653 ast_play_and_wait(chan, "vm-msgsaved"); 13654 cmd = '0'; 13655 } else { 13656 ast_play_and_wait(chan, "vm-deleted"); 13657 DELETE(tempfile, -1, tempfile, vmu); 13658 cmd = '0'; 13659 } 13660 } 13661 return cmd; 13662 default: 13663 /* If the caller is an ouside caller, and the review option is enabled, 13664 allow them to review the message, but let the owner of the box review 13665 their OGM's */ 13666 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13667 return cmd; 13668 if (msg_exists) { 13669 cmd = ast_play_and_wait(chan, "vm-review"); 13670 if (!cmd && outsidecaller) { 13671 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13672 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13673 } else if (flag) { 13674 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13675 } 13676 } 13677 } else { 13678 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13679 if (!cmd) 13680 cmd = ast_waitfordigit(chan, 600); 13681 } 13682 13683 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13684 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13685 if (!cmd) 13686 cmd = ast_waitfordigit(chan, 600); 13687 } 13688 #if 0 13689 if (!cmd) 13690 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13691 #endif 13692 if (!cmd) 13693 cmd = ast_waitfordigit(chan, 6000); 13694 if (!cmd) { 13695 attempts++; 13696 } 13697 if (attempts > max_attempts) { 13698 cmd = 't'; 13699 } 13700 } 13701 } 13702 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13703 /* Hang up or timeout, so delete the recording. */ 13704 ast_filedelete(tempfile, NULL); 13705 } 13706 13707 if (cmd != 't' && outsidecaller) 13708 ast_play_and_wait(chan, "vm-goodbye"); 13709 13710 return cmd; 13711 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11486 of file app_voicemail.c.
References inboxcount2(), queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11487 { 11488 int new = 0, old = 0, urgent = 0; 11489 11490 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11491 11492 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11493 mwi_sub->old_urgent = urgent; 11494 mwi_sub->old_new = new; 11495 mwi_sub->old_old = old; 11496 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11497 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11498 } 11499 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11501 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().
11502 { 11503 struct mwi_sub *mwi_sub; 11504 11505 AST_RWLIST_RDLOCK(&mwi_subs); 11506 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11507 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11508 poll_subscribed_mailbox(mwi_sub); 11509 } 11510 } 11511 AST_RWLIST_UNLOCK(&mwi_subs); 11512 }
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 12592 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().
12592 { 12593 struct ast_config *pwconf; 12594 struct ast_flags config_flags = { 0 }; 12595 12596 pwconf = ast_config_load(secretfn, config_flags); 12597 if (valid_config(pwconf)) { 12598 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12599 if (val) { 12600 ast_copy_string(password, val, passwordlen); 12601 ast_config_destroy(pwconf); 12602 return; 12603 } 12604 ast_config_destroy(pwconf); 12605 } 12606 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12607 }
static int reload | ( | void | ) | [static] |
Definition at line 13123 of file app_voicemail.c.
References load_config().
13124 { 13125 return load_config(1); 13126 }
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 12578 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().
12579 { 12580 int res = -1; 12581 char dir[PATH_MAX]; 12582 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12583 ast_debug(2, "About to try retrieving name file %s\n", dir); 12584 RETRIEVE(dir, -1, mailbox, context); 12585 if (ast_fileexists(dir, NULL, NULL)) { 12586 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12587 } 12588 DISPOSE(dir, -1); 12589 return res; 12590 }
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 11143 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().
11144 { 11145 struct ast_config *cfg; 11146 const char *cat = NULL; 11147 11148 if (!(cfg = ast_load_realtime_multientry("voicemail", 11149 "context", context, SENTINEL))) { 11150 return CLI_FAILURE; 11151 } 11152 11153 ast_cli(fd, 11154 "\n" 11155 "=============================================================\n" 11156 "=== Configured Voicemail Users ==============================\n" 11157 "=============================================================\n" 11158 "===\n"); 11159 11160 while ((cat = ast_category_browse(cfg, cat))) { 11161 struct ast_variable *var = NULL; 11162 ast_cli(fd, 11163 "=== Mailbox ...\n" 11164 "===\n"); 11165 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11166 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11167 ast_cli(fd, 11168 "===\n" 11169 "=== ---------------------------------------------------------\n" 11170 "===\n"); 11171 } 11172 11173 ast_cli(fd, 11174 "=============================================================\n" 11175 "\n"); 11176 11177 ast_config_destroy(cfg); 11178 11179 return CLI_SUCCESS; 11180 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11648 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().
11649 { 11650 int errcode; 11651 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11652 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11653 AST_EVENT_IE_END); 11654 11655 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11656 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11657 AST_EVENT_IE_END); 11658 11659 if (mwi_sub_sub) 11660 ast_event_report_subs(mwi_sub_sub); 11661 11662 poll_thread_run = 1; 11663 11664 if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) { 11665 ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode)); 11666 } 11667 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11669 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().
11670 { 11671 poll_thread_run = 0; 11672 11673 if (mwi_sub_sub) { 11674 ast_event_unsubscribe(mwi_sub_sub); 11675 mwi_sub_sub = NULL; 11676 } 11677 11678 if (mwi_unsub_sub) { 11679 ast_event_unsubscribe(mwi_unsub_sub); 11680 mwi_unsub_sub = NULL; 11681 } 11682 11683 ast_mutex_lock(&poll_lock); 11684 ast_cond_signal(&poll_cond); 11685 ast_mutex_unlock(&poll_lock); 11686 11687 pthread_join(poll_thread, NULL); 11688 11689 poll_thread = AST_PTHREADT_NULL; 11690 }
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 11815 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().
11816 { 11817 char *current; 11818 11819 /* Add 16 for fudge factor */ 11820 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11821 11822 ast_str_reset(str); 11823 11824 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11825 for (current = (char *) value; *current; current++) { 11826 if (*current == '\\') { 11827 current++; 11828 if (!*current) { 11829 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11830 break; 11831 } 11832 switch (*current) { 11833 case '\\': 11834 ast_str_append(&str, 0, "\\"); 11835 break; 11836 case 'r': 11837 ast_str_append(&str, 0, "\r"); 11838 break; 11839 case 'n': 11840 #ifdef IMAP_STORAGE 11841 if (!str->used || str->str[str->used - 1] != '\r') { 11842 ast_str_append(&str, 0, "\r"); 11843 } 11844 #endif 11845 ast_str_append(&str, 0, "\n"); 11846 break; 11847 case 't': 11848 ast_str_append(&str, 0, "\t"); 11849 break; 11850 default: 11851 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11852 break; 11853 } 11854 } else { 11855 ast_str_append(&str, 0, "%c", *current); 11856 } 11857 } 11858 11859 return ast_str_buffer(str); 11860 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13128 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().
13129 { 13130 int res; 13131 13132 res = ast_unregister_application(app); 13133 res |= ast_unregister_application(app2); 13134 res |= ast_unregister_application(app3); 13135 res |= ast_unregister_application(app4); 13136 res |= ast_unregister_application(sayname_app); 13137 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13138 res |= ast_manager_unregister("VoicemailUsersList"); 13139 res |= ast_data_unregister(NULL); 13140 #ifdef TEST_FRAMEWORK 13141 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13142 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13143 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13144 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13145 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13146 #endif 13147 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13148 ast_uninstall_vm_functions(); 13149 ao2_ref(inprocess_container, -1); 13150 13151 if (poll_thread != AST_PTHREADT_NULL) 13152 stop_poll_thread(); 13153 13154 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13155 ast_unload_realtime("voicemail"); 13156 ast_unload_realtime("voicemail_data"); 13157 13158 free_vm_users(); 13159 free_vm_zones(); 13160 return res; 13161 }
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 9823 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().
09826 { 09827 int useadsi = 0, valid = 0, logretries = 0; 09828 char password[AST_MAX_EXTENSION]="", *passptr; 09829 struct ast_vm_user vmus, *vmu = NULL; 09830 09831 /* If ADSI is supported, setup login screen */ 09832 adsi_begin(chan, &useadsi); 09833 if (!skipuser && useadsi) 09834 adsi_login(chan); 09835 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09836 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09837 return -1; 09838 } 09839 09840 /* Authenticate them and get their mailbox/password */ 09841 09842 while (!valid && (logretries < max_logins)) { 09843 /* Prompt for, and read in the username */ 09844 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09845 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09846 return -1; 09847 } 09848 if (ast_strlen_zero(mailbox)) { 09849 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09850 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09851 } else { 09852 ast_verb(3, "Username not entered\n"); 09853 return -1; 09854 } 09855 } else if (mailbox[0] == '*') { 09856 /* user entered '*' */ 09857 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09858 if (ast_exists_extension(chan, chan->context, "a", 1, 09859 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09860 return -1; 09861 } 09862 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09863 mailbox[0] = '\0'; 09864 } 09865 09866 if (useadsi) 09867 adsi_password(chan); 09868 09869 if (!ast_strlen_zero(prefix)) { 09870 char fullusername[80] = ""; 09871 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09872 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09873 ast_copy_string(mailbox, fullusername, mailbox_size); 09874 } 09875 09876 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09877 vmu = find_user(&vmus, context, mailbox); 09878 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09879 /* saved password is blank, so don't bother asking */ 09880 password[0] = '\0'; 09881 } else { 09882 if (ast_streamfile(chan, vm_password, chan->language)) { 09883 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09884 return -1; 09885 } 09886 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09887 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09888 return -1; 09889 } else if (password[0] == '*') { 09890 /* user entered '*' */ 09891 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09892 if (ast_exists_extension(chan, chan->context, "a", 1, 09893 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09894 mailbox[0] = '*'; 09895 return -1; 09896 } 09897 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09898 mailbox[0] = '\0'; 09899 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09900 vmu = NULL; 09901 } 09902 } 09903 09904 if (vmu) { 09905 passptr = vmu->password; 09906 if (passptr[0] == '-') passptr++; 09907 } 09908 if (vmu && !strcmp(passptr, password)) 09909 valid++; 09910 else { 09911 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09912 if (!ast_strlen_zero(prefix)) 09913 mailbox[0] = '\0'; 09914 } 09915 logretries++; 09916 if (!valid) { 09917 if (skipuser || logretries >= max_logins) { 09918 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09919 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09920 return -1; 09921 } 09922 } else { 09923 if (useadsi) 09924 adsi_login(chan); 09925 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09926 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09927 return -1; 09928 } 09929 } 09930 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09931 return -1; 09932 } 09933 } 09934 if (!valid && (logretries >= max_logins)) { 09935 ast_stopstream(chan); 09936 ast_play_and_wait(chan, "vm-goodbye"); 09937 return -1; 09938 } 09939 if (vmu && !skipuser) { 09940 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09941 } 09942 return 0; 09943 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11038 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().
11039 { 11040 struct ast_vm_user svm; 11041 char *context, *box; 11042 AST_DECLARE_APP_ARGS(args, 11043 AST_APP_ARG(mbox); 11044 AST_APP_ARG(options); 11045 ); 11046 static int dep_warning = 0; 11047 11048 if (ast_strlen_zero(data)) { 11049 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 11050 return -1; 11051 } 11052 11053 if (!dep_warning) { 11054 dep_warning = 1; 11055 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 11056 } 11057 11058 box = ast_strdupa(data); 11059 11060 AST_STANDARD_APP_ARGS(args, box); 11061 11062 if (args.options) { 11063 } 11064 11065 if ((context = strchr(args.mbox, '@'))) { 11066 *context = '\0'; 11067 context++; 11068 } 11069 11070 if (find_user(&svm, context, args.mbox)) { 11071 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11072 } else 11073 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11074 11075 return 0; 11076 }
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 9802 of file app_voicemail.c.
References vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_browse_messages_vi(), and vm_browse_messages_zh().
Referenced by vm_execmain().
09803 { 09804 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09805 return vm_browse_messages_es(chan, vms, vmu); 09806 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09807 return vm_browse_messages_gr(chan, vms, vmu); 09808 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09809 return vm_browse_messages_he(chan, vms, vmu); 09810 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09811 return vm_browse_messages_it(chan, vms, vmu); 09812 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09813 return vm_browse_messages_pt(chan, vms, vmu); 09814 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09815 return vm_browse_messages_vi(chan, vms, vmu); 09816 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09817 return vm_browse_messages_zh(chan, vms, vmu); 09818 } else { /* Default to English syntax */ 09819 return vm_browse_messages_en(chan, vms, vmu); 09820 } 09821 }
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 9641 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().
09642 { 09643 int cmd = 0; 09644 09645 if (vms->lastmsg > -1) { 09646 cmd = play_message(chan, vmu, vms); 09647 } else { 09648 cmd = ast_play_and_wait(chan, "vm-youhave"); 09649 if (!cmd) 09650 cmd = ast_play_and_wait(chan, "vm-no"); 09651 if (!cmd) { 09652 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09653 cmd = ast_play_and_wait(chan, vms->fn); 09654 } 09655 if (!cmd) 09656 cmd = ast_play_and_wait(chan, "vm-messages"); 09657 } 09658 return cmd; 09659 }
static int vm_browse_messages_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Spanish syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9695 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().
09696 { 09697 int cmd; 09698 09699 if (vms->lastmsg > -1) { 09700 cmd = play_message(chan, vmu, vms); 09701 } else { 09702 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09703 if (!cmd) 09704 cmd = ast_play_and_wait(chan, "vm-messages"); 09705 if (!cmd) { 09706 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09707 cmd = ast_play_and_wait(chan, vms->fn); 09708 } 09709 } 09710 return cmd; 09711 }
static int vm_browse_messages_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Greek syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9589 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().
09590 { 09591 int cmd = 0; 09592 09593 if (vms->lastmsg > -1) { 09594 cmd = play_message(chan, vmu, vms); 09595 } else { 09596 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09597 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09598 if (!cmd) { 09599 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09600 cmd = ast_play_and_wait(chan, vms->fn); 09601 } 09602 if (!cmd) 09603 cmd = ast_play_and_wait(chan, "vm-messages"); 09604 } else { 09605 if (!cmd) 09606 cmd = ast_play_and_wait(chan, "vm-messages"); 09607 if (!cmd) { 09608 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09609 cmd = ast_play_and_wait(chan, vms->fn); 09610 } 09611 } 09612 } 09613 return cmd; 09614 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9617 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09618 { 09619 int cmd = 0; 09620 09621 if (vms->lastmsg > -1) { 09622 cmd = play_message(chan, vmu, vms); 09623 } else { 09624 if (!strcasecmp(vms->fn, "INBOX")) { 09625 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09626 } else { 09627 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09628 } 09629 } 09630 return cmd; 09631 }
static int vm_browse_messages_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Italian syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9669 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().
09670 { 09671 int cmd; 09672 09673 if (vms->lastmsg > -1) { 09674 cmd = play_message(chan, vmu, vms); 09675 } else { 09676 cmd = ast_play_and_wait(chan, "vm-no"); 09677 if (!cmd) 09678 cmd = ast_play_and_wait(chan, "vm-message"); 09679 if (!cmd) { 09680 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09681 cmd = ast_play_and_wait(chan, vms->fn); 09682 } 09683 } 09684 return cmd; 09685 }
static int vm_browse_messages_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Portuguese syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9721 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().
09722 { 09723 int cmd; 09724 09725 if (vms->lastmsg > -1) { 09726 cmd = play_message(chan, vmu, vms); 09727 } else { 09728 cmd = ast_play_and_wait(chan, "vm-no"); 09729 if (!cmd) { 09730 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09731 cmd = ast_play_and_wait(chan, vms->fn); 09732 } 09733 if (!cmd) 09734 cmd = ast_play_and_wait(chan, "vm-messages"); 09735 } 09736 return cmd; 09737 }
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 9775 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().
09776 { 09777 int cmd = 0; 09778 09779 if (vms->lastmsg > -1) { 09780 cmd = play_message(chan, vmu, vms); 09781 } else { 09782 cmd = ast_play_and_wait(chan, "vm-no"); 09783 if (!cmd) { 09784 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09785 cmd = ast_play_and_wait(chan, vms->fn); 09786 } 09787 } 09788 return cmd; 09789 }
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 9747 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().
09748 { 09749 int cmd; 09750 09751 if (vms->lastmsg > -1) { 09752 cmd = play_message(chan, vmu, vms); 09753 } else { 09754 cmd = ast_play_and_wait(chan, "vm-you"); 09755 if (!cmd) 09756 cmd = ast_play_and_wait(chan, "vm-haveno"); 09757 if (!cmd) 09758 cmd = ast_play_and_wait(chan, "vm-messages"); 09759 if (!cmd) { 09760 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09761 cmd = ast_play_and_wait(chan, vms->fn); 09762 } 09763 } 09764 return cmd; 09765 }
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 10697 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().
10698 { 10699 int res = 0; 10700 char *tmp; 10701 struct leave_vm_options leave_options; 10702 struct ast_flags flags = { 0 }; 10703 char *opts[OPT_ARG_ARRAY_SIZE]; 10704 AST_DECLARE_APP_ARGS(args, 10705 AST_APP_ARG(argv0); 10706 AST_APP_ARG(argv1); 10707 ); 10708 10709 memset(&leave_options, 0, sizeof(leave_options)); 10710 10711 if (chan->_state != AST_STATE_UP) 10712 ast_answer(chan); 10713 10714 if (!ast_strlen_zero(data)) { 10715 tmp = ast_strdupa(data); 10716 AST_STANDARD_APP_ARGS(args, tmp); 10717 if (args.argc == 2) { 10718 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10719 return -1; 10720 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10721 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10722 int gain; 10723 10724 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10725 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10726 return -1; 10727 } else { 10728 leave_options.record_gain = (signed char) gain; 10729 } 10730 } 10731 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10732 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10733 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10734 } 10735 } 10736 } else { 10737 char temp[256]; 10738 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10739 if (res < 0) 10740 return res; 10741 if (ast_strlen_zero(temp)) 10742 return 0; 10743 args.argv0 = ast_strdupa(temp); 10744 } 10745 10746 res = leave_voicemail(chan, args.argv0, &leave_options); 10747 if (res == 't') { 10748 ast_play_and_wait(chan, "vm-goodbye"); 10749 res = 0; 10750 } 10751 10752 if (res == OPERATOR_EXIT) { 10753 res = 0; 10754 } 10755 10756 if (res == ERROR_LOCK_PATH) { 10757 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10758 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10759 res = 0; 10760 } 10761 10762 return res; 10763 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9945 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().
09946 { 09947 /* XXX This is, admittedly, some pretty horrendous code. For some 09948 reason it just seemed a lot easier to do with GOTO's. I feel 09949 like I'm back in my GWBASIC days. XXX */ 09950 int res = -1; 09951 int cmd = 0; 09952 int valid = 0; 09953 char prefixstr[80] =""; 09954 char ext_context[256]=""; 09955 int box; 09956 int useadsi = 0; 09957 int skipuser = 0; 09958 struct vm_state vms; 09959 struct ast_vm_user *vmu = NULL, vmus; 09960 char *context = NULL; 09961 int silentexit = 0; 09962 struct ast_flags flags = { 0 }; 09963 signed char record_gain = 0; 09964 int play_auto = 0; 09965 int play_folder = 0; 09966 int in_urgent = 0; 09967 #ifdef IMAP_STORAGE 09968 int deleted = 0; 09969 #endif 09970 09971 /* Add the vm_state to the active list and keep it active */ 09972 memset(&vms, 0, sizeof(vms)); 09973 09974 vms.lastmsg = -1; 09975 09976 memset(&vmus, 0, sizeof(vmus)); 09977 09978 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09979 if (chan->_state != AST_STATE_UP) { 09980 ast_debug(1, "Before ast_answer\n"); 09981 ast_answer(chan); 09982 } 09983 09984 if (!ast_strlen_zero(data)) { 09985 char *opts[OPT_ARG_ARRAY_SIZE]; 09986 char *parse; 09987 AST_DECLARE_APP_ARGS(args, 09988 AST_APP_ARG(argv0); 09989 AST_APP_ARG(argv1); 09990 ); 09991 09992 parse = ast_strdupa(data); 09993 09994 AST_STANDARD_APP_ARGS(args, parse); 09995 09996 if (args.argc == 2) { 09997 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09998 return -1; 09999 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10000 int gain; 10001 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 10002 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10003 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10004 return -1; 10005 } else { 10006 record_gain = (signed char) gain; 10007 } 10008 } else { 10009 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 10010 } 10011 } 10012 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 10013 play_auto = 1; 10014 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 10015 /* See if it is a folder name first */ 10016 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 10017 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 10018 play_folder = -1; 10019 } 10020 } else { 10021 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 10022 } 10023 } else { 10024 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 10025 } 10026 if (play_folder > 9 || play_folder < 0) { 10027 ast_log(AST_LOG_WARNING, 10028 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 10029 opts[OPT_ARG_PLAYFOLDER]); 10030 play_folder = 0; 10031 } 10032 } 10033 } else { 10034 /* old style options parsing */ 10035 while (*(args.argv0)) { 10036 if (*(args.argv0) == 's') 10037 ast_set_flag(&flags, OPT_SILENT); 10038 else if (*(args.argv0) == 'p') 10039 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 10040 else 10041 break; 10042 (args.argv0)++; 10043 } 10044 10045 } 10046 10047 valid = ast_test_flag(&flags, OPT_SILENT); 10048 10049 if ((context = strchr(args.argv0, '@'))) 10050 *context++ = '\0'; 10051 10052 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 10053 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 10054 else 10055 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 10056 10057 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 10058 skipuser++; 10059 else 10060 valid = 0; 10061 } 10062 10063 if (!valid) 10064 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 10065 10066 ast_debug(1, "After vm_authenticate\n"); 10067 10068 if (vms.username[0] == '*') { 10069 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 10070 10071 /* user entered '*' */ 10072 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10073 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 10074 res = 0; /* prevent hangup */ 10075 goto out; 10076 } 10077 } 10078 10079 if (!res) { 10080 valid = 1; 10081 if (!skipuser) 10082 vmu = &vmus; 10083 } else { 10084 res = 0; 10085 } 10086 10087 /* If ADSI is supported, setup login screen */ 10088 adsi_begin(chan, &useadsi); 10089 10090 ast_test_suite_assert(valid); 10091 if (!valid) { 10092 goto out; 10093 } 10094 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10095 10096 #ifdef IMAP_STORAGE 10097 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10098 pthread_setspecific(ts_vmstate.key, &vms); 10099 10100 vms.interactive = 1; 10101 vms.updated = 1; 10102 if (vmu) 10103 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10104 vmstate_insert(&vms); 10105 init_vm_state(&vms); 10106 #endif 10107 10108 /* Set language from config to override channel language */ 10109 if (!ast_strlen_zero(vmu->language)) 10110 ast_string_field_set(chan, language, vmu->language); 10111 10112 /* Retrieve urgent, old and new message counts */ 10113 ast_debug(1, "Before open_mailbox\n"); 10114 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10115 if (res < 0) 10116 goto out; 10117 vms.oldmessages = vms.lastmsg + 1; 10118 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10119 /* check INBOX */ 10120 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10121 if (res < 0) 10122 goto out; 10123 vms.newmessages = vms.lastmsg + 1; 10124 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10125 /* Start in Urgent */ 10126 in_urgent = 1; 10127 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10128 if (res < 0) 10129 goto out; 10130 vms.urgentmessages = vms.lastmsg + 1; 10131 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10132 10133 /* Select proper mailbox FIRST!! */ 10134 if (play_auto) { 10135 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10136 if (vms.urgentmessages) { 10137 in_urgent = 1; 10138 res = open_mailbox(&vms, vmu, 11); 10139 } else { 10140 in_urgent = 0; 10141 res = open_mailbox(&vms, vmu, play_folder); 10142 } 10143 if (res < 0) 10144 goto out; 10145 10146 /* If there are no new messages, inform the user and hangup */ 10147 if (vms.lastmsg == -1) { 10148 in_urgent = 0; 10149 cmd = vm_browse_messages(chan, &vms, vmu); 10150 res = 0; 10151 goto out; 10152 } 10153 } else { 10154 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10155 /* If we only have old messages start here */ 10156 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10157 in_urgent = 0; 10158 play_folder = 1; 10159 if (res < 0) 10160 goto out; 10161 } else if (!vms.urgentmessages && vms.newmessages) { 10162 /* If we have new messages but none are urgent */ 10163 in_urgent = 0; 10164 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10165 if (res < 0) 10166 goto out; 10167 } 10168 } 10169 10170 if (useadsi) 10171 adsi_status(chan, &vms); 10172 res = 0; 10173 10174 /* Check to see if this is a new user */ 10175 if (!strcasecmp(vmu->mailbox, vmu->password) && 10176 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10177 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10178 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10179 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10180 if ((cmd == 't') || (cmd == '#')) { 10181 /* Timeout */ 10182 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10183 res = 0; 10184 goto out; 10185 } else if (cmd < 0) { 10186 /* Hangup */ 10187 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10188 res = -1; 10189 goto out; 10190 } 10191 } 10192 #ifdef IMAP_STORAGE 10193 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10194 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10195 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10196 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10197 } 10198 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10199 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10200 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10201 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10202 } 10203 #endif 10204 10205 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10206 if (play_auto) { 10207 cmd = '1'; 10208 } else { 10209 cmd = vm_intro(chan, vmu, &vms); 10210 } 10211 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10212 10213 vms.repeats = 0; 10214 vms.starting = 1; 10215 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10216 /* Run main menu */ 10217 switch (cmd) { 10218 case '1': /* First message */ 10219 vms.curmsg = 0; 10220 /* Fall through */ 10221 case '5': /* Play current message */ 10222 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10223 cmd = vm_browse_messages(chan, &vms, vmu); 10224 break; 10225 case '2': /* Change folders */ 10226 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10227 if (useadsi) 10228 adsi_folders(chan, 0, "Change to folder..."); 10229 10230 cmd = get_folder2(chan, "vm-changeto", 0); 10231 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10232 if (cmd == '#') { 10233 cmd = 0; 10234 } else if (cmd > 0) { 10235 cmd = cmd - '0'; 10236 res = close_mailbox(&vms, vmu); 10237 if (res == ERROR_LOCK_PATH) 10238 goto out; 10239 /* If folder is not urgent, set in_urgent to zero! */ 10240 if (cmd != 11) in_urgent = 0; 10241 res = open_mailbox(&vms, vmu, cmd); 10242 if (res < 0) 10243 goto out; 10244 play_folder = cmd; 10245 cmd = 0; 10246 } 10247 if (useadsi) 10248 adsi_status2(chan, &vms); 10249 10250 if (!cmd) { 10251 cmd = vm_play_folder_name(chan, vms.vmbox); 10252 } 10253 10254 vms.starting = 1; 10255 vms.curmsg = 0; 10256 break; 10257 case '3': /* Advanced options */ 10258 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10259 cmd = 0; 10260 vms.repeats = 0; 10261 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10262 switch (cmd) { 10263 case '1': /* Reply */ 10264 if (vms.lastmsg > -1 && !vms.starting) { 10265 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10266 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10267 res = cmd; 10268 goto out; 10269 } 10270 } else { 10271 cmd = ast_play_and_wait(chan, "vm-sorry"); 10272 } 10273 cmd = 't'; 10274 break; 10275 case '2': /* Callback */ 10276 if (!vms.starting) 10277 ast_verb(3, "Callback Requested\n"); 10278 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10279 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10280 if (cmd == 9) { 10281 silentexit = 1; 10282 goto out; 10283 } else if (cmd == ERROR_LOCK_PATH) { 10284 res = cmd; 10285 goto out; 10286 } 10287 } else { 10288 cmd = ast_play_and_wait(chan, "vm-sorry"); 10289 } 10290 cmd = 't'; 10291 break; 10292 case '3': /* Envelope */ 10293 if (vms.lastmsg > -1 && !vms.starting) { 10294 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10295 if (cmd == ERROR_LOCK_PATH) { 10296 res = cmd; 10297 goto out; 10298 } 10299 } else { 10300 cmd = ast_play_and_wait(chan, "vm-sorry"); 10301 } 10302 cmd = 't'; 10303 break; 10304 case '4': /* Dialout */ 10305 if (!ast_strlen_zero(vmu->dialout)) { 10306 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10307 if (cmd == 9) { 10308 silentexit = 1; 10309 goto out; 10310 } 10311 } else { 10312 cmd = ast_play_and_wait(chan, "vm-sorry"); 10313 } 10314 cmd = 't'; 10315 break; 10316 10317 case '5': /* Leave VoiceMail */ 10318 if (ast_test_flag(vmu, VM_SVMAIL)) { 10319 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10320 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10321 res = cmd; 10322 goto out; 10323 } 10324 } else { 10325 cmd = ast_play_and_wait(chan, "vm-sorry"); 10326 } 10327 cmd = 't'; 10328 break; 10329 10330 case '*': /* Return to main menu */ 10331 cmd = 't'; 10332 break; 10333 10334 default: 10335 cmd = 0; 10336 if (!vms.starting) { 10337 cmd = ast_play_and_wait(chan, "vm-toreply"); 10338 } 10339 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10340 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10341 } 10342 if (!cmd && !vms.starting) { 10343 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10344 } 10345 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10346 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10347 } 10348 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10349 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10350 } 10351 if (!cmd) { 10352 cmd = ast_play_and_wait(chan, "vm-starmain"); 10353 } 10354 if (!cmd) { 10355 cmd = ast_waitfordigit(chan, 6000); 10356 } 10357 if (!cmd) { 10358 vms.repeats++; 10359 } 10360 if (vms.repeats > 3) { 10361 cmd = 't'; 10362 } 10363 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10364 } 10365 } 10366 if (cmd == 't') { 10367 cmd = 0; 10368 vms.repeats = 0; 10369 } 10370 break; 10371 case '4': /* Go to the previous message */ 10372 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10373 if (vms.curmsg > 0) { 10374 vms.curmsg--; 10375 cmd = play_message(chan, vmu, &vms); 10376 } else { 10377 /* Check if we were listening to new 10378 messages. If so, go to Urgent messages 10379 instead of saying "no more messages" 10380 */ 10381 if (in_urgent == 0 && vms.urgentmessages > 0) { 10382 /* Check for Urgent messages */ 10383 in_urgent = 1; 10384 res = close_mailbox(&vms, vmu); 10385 if (res == ERROR_LOCK_PATH) 10386 goto out; 10387 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10388 if (res < 0) 10389 goto out; 10390 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10391 vms.curmsg = vms.lastmsg; 10392 if (vms.lastmsg < 0) { 10393 cmd = ast_play_and_wait(chan, "vm-nomore"); 10394 } 10395 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10396 vms.curmsg = vms.lastmsg; 10397 cmd = play_message(chan, vmu, &vms); 10398 } else { 10399 cmd = ast_play_and_wait(chan, "vm-nomore"); 10400 } 10401 } 10402 break; 10403 case '6': /* Go to the next message */ 10404 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10405 if (vms.curmsg < vms.lastmsg) { 10406 vms.curmsg++; 10407 cmd = play_message(chan, vmu, &vms); 10408 } else { 10409 if (in_urgent && vms.newmessages > 0) { 10410 /* Check if we were listening to urgent 10411 * messages. If so, go to regular new messages 10412 * instead of saying "no more messages" 10413 */ 10414 in_urgent = 0; 10415 res = close_mailbox(&vms, vmu); 10416 if (res == ERROR_LOCK_PATH) 10417 goto out; 10418 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10419 if (res < 0) 10420 goto out; 10421 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10422 vms.curmsg = -1; 10423 if (vms.lastmsg < 0) { 10424 cmd = ast_play_and_wait(chan, "vm-nomore"); 10425 } 10426 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10427 vms.curmsg = 0; 10428 cmd = play_message(chan, vmu, &vms); 10429 } else { 10430 cmd = ast_play_and_wait(chan, "vm-nomore"); 10431 } 10432 } 10433 break; 10434 case '7': /* Delete the current message */ 10435 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10436 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10437 if (useadsi) 10438 adsi_delete(chan, &vms); 10439 if (vms.deleted[vms.curmsg]) { 10440 if (play_folder == 0) { 10441 if (in_urgent) { 10442 vms.urgentmessages--; 10443 } else { 10444 vms.newmessages--; 10445 } 10446 } 10447 else if (play_folder == 1) 10448 vms.oldmessages--; 10449 cmd = ast_play_and_wait(chan, "vm-deleted"); 10450 } else { 10451 if (play_folder == 0) { 10452 if (in_urgent) { 10453 vms.urgentmessages++; 10454 } else { 10455 vms.newmessages++; 10456 } 10457 } 10458 else if (play_folder == 1) 10459 vms.oldmessages++; 10460 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10461 } 10462 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10463 if (vms.curmsg < vms.lastmsg) { 10464 vms.curmsg++; 10465 cmd = play_message(chan, vmu, &vms); 10466 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10467 vms.curmsg = 0; 10468 cmd = play_message(chan, vmu, &vms); 10469 } else { 10470 /* Check if we were listening to urgent 10471 messages. If so, go to regular new messages 10472 instead of saying "no more messages" 10473 */ 10474 if (in_urgent == 1) { 10475 /* Check for new messages */ 10476 in_urgent = 0; 10477 res = close_mailbox(&vms, vmu); 10478 if (res == ERROR_LOCK_PATH) 10479 goto out; 10480 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10481 if (res < 0) 10482 goto out; 10483 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10484 vms.curmsg = -1; 10485 if (vms.lastmsg < 0) { 10486 cmd = ast_play_and_wait(chan, "vm-nomore"); 10487 } 10488 } else { 10489 cmd = ast_play_and_wait(chan, "vm-nomore"); 10490 } 10491 } 10492 } 10493 } else /* Delete not valid if we haven't selected a message */ 10494 cmd = 0; 10495 #ifdef IMAP_STORAGE 10496 deleted = 1; 10497 #endif 10498 break; 10499 10500 case '8': /* Forward the current message */ 10501 if (vms.lastmsg > -1) { 10502 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10503 if (cmd == ERROR_LOCK_PATH) { 10504 res = cmd; 10505 goto out; 10506 } 10507 } else { 10508 /* Check if we were listening to urgent 10509 messages. If so, go to regular new messages 10510 instead of saying "no more messages" 10511 */ 10512 if (in_urgent == 1 && vms.newmessages > 0) { 10513 /* Check for new messages */ 10514 in_urgent = 0; 10515 res = close_mailbox(&vms, vmu); 10516 if (res == ERROR_LOCK_PATH) 10517 goto out; 10518 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10519 if (res < 0) 10520 goto out; 10521 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10522 vms.curmsg = -1; 10523 if (vms.lastmsg < 0) { 10524 cmd = ast_play_and_wait(chan, "vm-nomore"); 10525 } 10526 } else { 10527 cmd = ast_play_and_wait(chan, "vm-nomore"); 10528 } 10529 } 10530 break; 10531 case '9': /* Save message to folder */ 10532 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10533 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10534 /* No message selected */ 10535 cmd = 0; 10536 break; 10537 } 10538 if (useadsi) 10539 adsi_folders(chan, 1, "Save to folder..."); 10540 cmd = get_folder2(chan, "vm-savefolder", 1); 10541 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10542 box = 0; /* Shut up compiler */ 10543 if (cmd == '#') { 10544 cmd = 0; 10545 break; 10546 } else if (cmd > 0) { 10547 box = cmd = cmd - '0'; 10548 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10549 if (cmd == ERROR_LOCK_PATH) { 10550 res = cmd; 10551 goto out; 10552 #ifndef IMAP_STORAGE 10553 } else if (!cmd) { 10554 vms.deleted[vms.curmsg] = 1; 10555 #endif 10556 } else { 10557 vms.deleted[vms.curmsg] = 0; 10558 vms.heard[vms.curmsg] = 0; 10559 } 10560 } 10561 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10562 if (useadsi) 10563 adsi_message(chan, &vms); 10564 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10565 if (!cmd) { 10566 cmd = ast_play_and_wait(chan, "vm-message"); 10567 if (!cmd) 10568 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10569 if (!cmd) 10570 cmd = ast_play_and_wait(chan, "vm-savedto"); 10571 if (!cmd) 10572 cmd = vm_play_folder_name(chan, vms.fn); 10573 } else { 10574 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10575 } 10576 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10577 if (vms.curmsg < vms.lastmsg) { 10578 vms.curmsg++; 10579 cmd = play_message(chan, vmu, &vms); 10580 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10581 vms.curmsg = 0; 10582 cmd = play_message(chan, vmu, &vms); 10583 } else { 10584 /* Check if we were listening to urgent 10585 messages. If so, go to regular new messages 10586 instead of saying "no more messages" 10587 */ 10588 if (in_urgent == 1 && vms.newmessages > 0) { 10589 /* Check for new messages */ 10590 in_urgent = 0; 10591 res = close_mailbox(&vms, vmu); 10592 if (res == ERROR_LOCK_PATH) 10593 goto out; 10594 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10595 if (res < 0) 10596 goto out; 10597 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10598 vms.curmsg = -1; 10599 if (vms.lastmsg < 0) { 10600 cmd = ast_play_and_wait(chan, "vm-nomore"); 10601 } 10602 } else { 10603 cmd = ast_play_and_wait(chan, "vm-nomore"); 10604 } 10605 } 10606 } 10607 break; 10608 case '*': /* Help */ 10609 if (!vms.starting) { 10610 cmd = ast_play_and_wait(chan, "vm-onefor"); 10611 if (!strncasecmp(chan->language, "he", 2)) { 10612 cmd = ast_play_and_wait(chan, "vm-for"); 10613 } 10614 if (!cmd) 10615 cmd = vm_play_folder_name(chan, vms.vmbox); 10616 if (!cmd) 10617 cmd = ast_play_and_wait(chan, "vm-opts"); 10618 if (!cmd) 10619 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10620 } else 10621 cmd = 0; 10622 break; 10623 case '0': /* Mailbox options */ 10624 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10625 if (useadsi) 10626 adsi_status(chan, &vms); 10627 break; 10628 default: /* Nothing */ 10629 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10630 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10631 break; 10632 } 10633 } 10634 if ((cmd == 't') || (cmd == '#')) { 10635 /* Timeout */ 10636 res = 0; 10637 } else { 10638 /* Hangup */ 10639 res = -1; 10640 } 10641 10642 out: 10643 if (res > -1) { 10644 ast_stopstream(chan); 10645 adsi_goodbye(chan); 10646 if (valid && res != OPERATOR_EXIT) { 10647 if (silentexit) 10648 res = ast_play_and_wait(chan, "vm-dialout"); 10649 else 10650 res = ast_play_and_wait(chan, "vm-goodbye"); 10651 } 10652 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10653 res = 0; 10654 } 10655 if (useadsi) 10656 ast_adsi_unload_session(chan); 10657 } 10658 if (vmu) 10659 close_mailbox(&vms, vmu); 10660 if (valid) { 10661 int new = 0, old = 0, urgent = 0; 10662 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10663 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10664 /* Urgent flag not passwd to externnotify here */ 10665 run_externnotify(vmu->context, vmu->mailbox, NULL); 10666 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10667 queue_mwi_event(ext_context, urgent, new, old); 10668 } 10669 #ifdef IMAP_STORAGE 10670 /* expunge message - use UID Expunge if supported on IMAP server*/ 10671 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10672 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10673 ast_mutex_lock(&vms.lock); 10674 #ifdef HAVE_IMAP_TK2006 10675 if (LEVELUIDPLUS (vms.mailstream)) { 10676 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10677 } else 10678 #endif 10679 mail_expunge(vms.mailstream); 10680 ast_mutex_unlock(&vms.lock); 10681 } 10682 /* before we delete the state, we should copy pertinent info 10683 * back to the persistent model */ 10684 if (vmu) { 10685 vmstate_delete(&vms); 10686 } 10687 #endif 10688 if (vmu) 10689 free_user(vmu); 10690 10691 #ifdef IMAP_STORAGE 10692 pthread_setspecific(ts_vmstate.key, NULL); 10693 #endif 10694 return res; 10695 }
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/1M"); 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/1M"); 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 11463 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and vm_users_data_provider_get_helper().
11465 { 11466 struct ast_vm_user *user; 11467 11468 AST_LIST_LOCK(&users); 11469 AST_LIST_TRAVERSE(&users, user, list) { 11470 vm_users_data_provider_get_helper(search, data_root, user); 11471 } 11472 AST_LIST_UNLOCK(&users); 11473 11474 return 0; 11475 }
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 11416 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().
11418 { 11419 struct ast_data *data_user, *data_zone; 11420 struct ast_data *data_state; 11421 struct vm_zone *zone = NULL; 11422 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11423 char ext_context[256] = ""; 11424 11425 data_user = ast_data_add_node(data_root, "user"); 11426 if (!data_user) { 11427 return -1; 11428 } 11429 11430 ast_data_add_structure(ast_vm_user, data_user, user); 11431 11432 AST_LIST_LOCK(&zones); 11433 AST_LIST_TRAVERSE(&zones, zone, list) { 11434 if (!strcmp(zone->name, user->zonetag)) { 11435 break; 11436 } 11437 } 11438 AST_LIST_UNLOCK(&zones); 11439 11440 /* state */ 11441 data_state = ast_data_add_node(data_user, "state"); 11442 if (!data_state) { 11443 return -1; 11444 } 11445 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11446 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11447 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11448 ast_data_add_int(data_state, "newmsg", newmsg); 11449 ast_data_add_int(data_state, "oldmsg", oldmsg); 11450 11451 if (zone) { 11452 data_zone = ast_data_add_node(data_user, "zone"); 11453 ast_data_add_structure(vm_zone, data_zone, zone); 11454 } 11455 11456 if (!ast_data_search_match(search, data_user)) { 11457 ast_data_remove_node(data_root, data_user); 11458 } 11459 11460 return 0; 11461 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11102 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().
11103 { 11104 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11105 struct ast_vm_user vmus; 11106 char *options = NULL; 11107 int silent = 0, skipuser = 0; 11108 int res = -1; 11109 11110 if (data) { 11111 s = ast_strdupa(data); 11112 user = strsep(&s, ","); 11113 options = strsep(&s, ","); 11114 if (user) { 11115 s = user; 11116 user = strsep(&s, "@"); 11117 context = strsep(&s, ""); 11118 if (!ast_strlen_zero(user)) 11119 skipuser++; 11120 ast_copy_string(mailbox, user, sizeof(mailbox)); 11121 } 11122 } 11123 11124 if (options) { 11125 silent = (strchr(options, 's')) != NULL; 11126 } 11127 11128 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11129 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11130 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11131 ast_play_and_wait(chan, "auth-thankyou"); 11132 res = 0; 11133 } else if (mailbox[0] == '*') { 11134 /* user entered '*' */ 11135 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11136 res = 0; /* prevent hangup */ 11137 } 11138 } 11139 11140 return res; 11141 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12642 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().
12643 { 12644 char *context; 12645 char *args_copy; 12646 int res; 12647 12648 if (ast_strlen_zero(data)) { 12649 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n"); 12650 return -1; 12651 } 12652 12653 args_copy = ast_strdupa(data); 12654 if ((context = strchr(args_copy, '@'))) { 12655 *context++ = '\0'; 12656 } else { 12657 context = "default"; 12658 } 12659 12660 if ((res = sayname(chan, args_copy, context) < 0)) { 12661 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12662 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12663 if (!res) { 12664 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12665 } 12666 } 12667 12668 return res; 12669 }
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 12609 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().
12609 { 12610 struct ast_config *conf; 12611 struct ast_category *cat; 12612 struct ast_variable *var; 12613 int res = -1; 12614 12615 if (!(conf = ast_config_new())) { 12616 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12617 return res; 12618 } 12619 if (!(cat = ast_category_new("general", "", 1))) { 12620 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12621 ast_config_destroy(conf); 12622 return res; 12623 } 12624 if (!(var = ast_variable_new("password", password, ""))) { 12625 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12626 ast_config_destroy(conf); 12627 ast_category_destroy(cat); 12628 return res; 12629 } 12630 ast_category_append(conf, cat); 12631 ast_variable_append(cat, var); 12632 if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12633 res = 0; 12634 } else { 12635 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12636 } 12637 12638 ast_config_destroy(conf); 12639 return res; 12640 }
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 11341 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 11097 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 11477 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().