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 } |
| enum | vm_option_args { 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) } |
| enum | vm_passwordlocation { 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 438 of file app_voicemail.c.
| #define BASELINELEN 72 |
Definition at line 461 of file app_voicemail.c.
Referenced by ochar().
| #define BASEMAXINLINE 256 |
Definition at line 462 of file app_voicemail.c.
Referenced by base_encode(), and inbuf().
| #define CHUNKSIZE 65536 |
Definition at line 435 of file app_voicemail.c.
| #define COMMAND_TIMEOUT 5000 |
Definition at line 431 of file app_voicemail.c.
| #define COPY | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h | ) | (copy_plain_file(g,h)); |
Definition at line 748 of file app_voicemail.c.
Referenced by copy_message(), and save_to_folder().
| #define DATA_EXPORT_VM_USERS | ( | USER | ) |
Definition at line 11367 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 11394 of file app_voicemail.c.
| #define DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
Definition at line 443 of file app_voicemail.c.
Referenced by actual_load_config().
| #define DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
Definition at line 445 of file app_voicemail.c.
Referenced by actual_load_config().
| #define DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
Definition at line 446 of file app_voicemail.c.
Referenced by actual_load_config().
| #define DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
Definition at line 444 of file app_voicemail.c.
Referenced by actual_load_config().
| #define DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
Definition at line 447 of file app_voicemail.c.
Referenced by actual_load_config().
| #define DEFAULT_POLL_FREQ 30 |
By default, poll every 30 seconds
Definition at line 818 of file app_voicemail.c.
Referenced by actual_load_config().
| #define DELETE | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (vm_delete(c)) |
Definition at line 749 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 744 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 466 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 491 of file app_voicemail.c.
| #define EXISTS | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 746 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 454 of file app_voicemail.c.
Referenced by leave_voicemail(), play_record_review(), and vm_forwardoptions().
| #define MAX_DATETIME_FORMAT 512 |
Definition at line 469 of file app_voicemail.c.
| #define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 470 of file app_voicemail.c.
| #define MAXMSG 100 |
Definition at line 456 of file app_voicemail.c.
Referenced by actual_load_config(), and apply_option().
| #define MAXMSGLIMIT 9999 |
Definition at line 457 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 459 of file app_voicemail.c.
Referenced by actual_load_config().
| #define OPERATOR_EXIT 300 |
Definition at line 492 of file app_voicemail.c.
Referenced by leave_voicemail(), vm_exec(), and vm_execmain().
| #define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 761 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
| #define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 760 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 747 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 743 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 452 of file app_voicemail.c.
| #define SMDI_MWI_WAIT_TIMEOUT 1000 |
Definition at line 429 of file app_voicemail.c.
Referenced by run_externnotify().
| #define STORE | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h, | |||||
| i, | |||||
| j | ) |
Definition at line 745 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 770 of file app_voicemail.c.
| #define VALID_DTMF "1234567890*#" |
Definition at line 448 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 485 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 483 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 484 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 482 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 476 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 480 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 479 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 490 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 489 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 488 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 473 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 481 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 472 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 474 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 477 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 486 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 478 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 475 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 487 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 685 of file app_voicemail.c.
| #define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 437 of file app_voicemail.c.
| #define VOICEMAIL_DIR_MODE 0777 |
Definition at line 433 of file app_voicemail.c.
| #define VOICEMAIL_FILE_MODE 0666 |
Definition at line 434 of file app_voicemail.c.
Referenced by add_email_attachment(), copy(), leave_voicemail(), and vm_mkftemp().
| enum vm_box |
Definition at line 495 of file app_voicemail.c.
00495 { 00496 NEW_FOLDER, 00497 OLD_FOLDER, 00498 WORK_FOLDER, 00499 FAMILY_FOLDER, 00500 FRIENDS_FOLDER, 00501 GREETINGS_FOLDER 00502 };
| enum vm_option_args |
Definition at line 516 of file app_voicemail.c.
00516 { 00517 OPT_ARG_RECORDGAIN = 0, 00518 OPT_ARG_PLAYFOLDER = 1, 00519 OPT_ARG_DTMFEXIT = 2, 00520 /* This *must* be the last value in this enum! */ 00521 OPT_ARG_ARRAY_SIZE = 3, 00522 };
| enum vm_option_flags |
| OPT_SILENT | |
| OPT_BUSY_GREETING | |
| OPT_UNAVAIL_GREETING | |
| OPT_RECORDGAIN | |
| OPT_PREPEND_MAILBOX | |
| OPT_AUTOPLAY | |
| OPT_DTMFEXIT | |
| OPT_MESSAGE_Urgent | |
| OPT_MESSAGE_PRIORITY |
Definition at line 504 of file app_voicemail.c.
00504 { 00505 OPT_SILENT = (1 << 0), 00506 OPT_BUSY_GREETING = (1 << 1), 00507 OPT_UNAVAIL_GREETING = (1 << 2), 00508 OPT_RECORDGAIN = (1 << 3), 00509 OPT_PREPEND_MAILBOX = (1 << 4), 00510 OPT_AUTOPLAY = (1 << 6), 00511 OPT_DTMFEXIT = (1 << 7), 00512 OPT_MESSAGE_Urgent = (1 << 8), 00513 OPT_MESSAGE_PRIORITY = (1 << 9) 00514 };
| enum vm_passwordlocation |
Definition at line 524 of file app_voicemail.c.
00524 { 00525 OPT_PWLOC_VOICEMAILCONF = 0, 00526 OPT_PWLOC_SPOOLDIR = 1, 00527 OPT_PWLOC_USERSCONF = 2, 00528 };
| static int __has_voicemail | ( | const char * | context, | |
| const char * | mailbox, | |||
| const char * | folder, | |||
| int | shortcircuit | |||
| ) | [static] |
Definition at line 5409 of file app_voicemail.c.
References ast_strlen_zero(), and VM_SPOOL_DIR.
Referenced by has_voicemail(), inboxcount2(), and messagecount().
05410 { 05411 DIR *dir; 05412 struct dirent *de; 05413 char fn[256]; 05414 int ret = 0; 05415 05416 /* If no mailbox, return immediately */ 05417 if (ast_strlen_zero(mailbox)) 05418 return 0; 05419 05420 if (ast_strlen_zero(folder)) 05421 folder = "INBOX"; 05422 if (ast_strlen_zero(context)) 05423 context = "default"; 05424 05425 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05426 05427 if (!(dir = opendir(fn))) 05428 return 0; 05429 05430 while ((de = readdir(dir))) { 05431 if (!strncasecmp(de->d_name, "msg", 3)) { 05432 if (shortcircuit) { 05433 ret = 1; 05434 break; 05435 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05436 ret++; 05437 } 05438 } 05439 } 05440 05441 closedir(dir); 05442 05443 return ret; 05444 }
| static int acf_mailbox_exists | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | args, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 11070 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().
11071 { 11072 struct ast_vm_user svm; 11073 AST_DECLARE_APP_ARGS(arg, 11074 AST_APP_ARG(mbox); 11075 AST_APP_ARG(context); 11076 ); 11077 11078 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11079 11080 if (ast_strlen_zero(arg.mbox)) { 11081 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11082 return -1; 11083 } 11084 11085 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11086 return 0; 11087 }
| static int actual_load_config | ( | int | reload, | |
| struct ast_config * | cfg, | |||
| struct ast_config * | ucfg | |||
| ) | [static] |
Definition at line 11904 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().
11905 { 11906 struct ast_vm_user *current; 11907 char *cat; 11908 struct ast_variable *var; 11909 const char *val; 11910 char *q, *stringp, *tmp; 11911 int x; 11912 int tmpadsi[4]; 11913 char secretfn[PATH_MAX] = ""; 11914 11915 #ifdef IMAP_STORAGE 11916 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11917 #endif 11918 /* set audio control prompts */ 11919 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11920 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11921 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11922 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11923 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11924 11925 /* Free all the users structure */ 11926 free_vm_users(); 11927 11928 /* Free all the zones structure */ 11929 free_vm_zones(); 11930 11931 AST_LIST_LOCK(&users); 11932 11933 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11934 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11935 11936 if (cfg) { 11937 /* General settings */ 11938 11939 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11940 val = "default"; 11941 ast_copy_string(userscontext, val, sizeof(userscontext)); 11942 /* Attach voice message to mail message ? */ 11943 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11944 val = "yes"; 11945 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11946 11947 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11948 val = "no"; 11949 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11950 11951 volgain = 0.0; 11952 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11953 sscanf(val, "%30lf", &volgain); 11954 11955 #ifdef ODBC_STORAGE 11956 strcpy(odbc_database, "asterisk"); 11957 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11958 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11959 } 11960 strcpy(odbc_table, "voicemessages"); 11961 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11962 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11963 } 11964 #endif 11965 /* Mail command */ 11966 strcpy(mailcmd, SENDMAIL); 11967 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11968 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11969 11970 maxsilence = 0; 11971 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11972 maxsilence = atoi(val); 11973 if (maxsilence > 0) 11974 maxsilence *= 1000; 11975 } 11976 11977 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11978 maxmsg = MAXMSG; 11979 } else { 11980 maxmsg = atoi(val); 11981 if (maxmsg < 0) { 11982 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11983 maxmsg = MAXMSG; 11984 } else if (maxmsg > MAXMSGLIMIT) { 11985 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11986 maxmsg = MAXMSGLIMIT; 11987 } 11988 } 11989 11990 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11991 maxdeletedmsg = 0; 11992 } else { 11993 if (sscanf(val, "%30d", &x) == 1) 11994 maxdeletedmsg = x; 11995 else if (ast_true(val)) 11996 maxdeletedmsg = MAXMSG; 11997 else 11998 maxdeletedmsg = 0; 11999 12000 if (maxdeletedmsg < 0) { 12001 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 12002 maxdeletedmsg = MAXMSG; 12003 } else if (maxdeletedmsg > MAXMSGLIMIT) { 12004 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 12005 maxdeletedmsg = MAXMSGLIMIT; 12006 } 12007 } 12008 12009 /* Load date format config for voicemail mail */ 12010 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 12011 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 12012 } 12013 12014 /* Load date format config for voicemail pager mail */ 12015 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 12016 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 12017 } 12018 12019 /* External password changing command */ 12020 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 12021 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12022 pwdchange = PWDCHANGE_EXTERNAL; 12023 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 12024 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12025 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 12026 } 12027 12028 /* External password validation command */ 12029 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 12030 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 12031 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 12032 } 12033 12034 #ifdef IMAP_STORAGE 12035 /* IMAP server address */ 12036 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 12037 ast_copy_string(imapserver, val, sizeof(imapserver)); 12038 } else { 12039 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 12040 } 12041 /* IMAP server port */ 12042 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 12043 ast_copy_string(imapport, val, sizeof(imapport)); 12044 } else { 12045 ast_copy_string(imapport, "143", sizeof(imapport)); 12046 } 12047 /* IMAP server flags */ 12048 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 12049 ast_copy_string(imapflags, val, sizeof(imapflags)); 12050 } 12051 /* IMAP server master username */ 12052 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 12053 ast_copy_string(authuser, val, sizeof(authuser)); 12054 } 12055 /* IMAP server master password */ 12056 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 12057 ast_copy_string(authpassword, val, sizeof(authpassword)); 12058 } 12059 /* Expunge on exit */ 12060 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 12061 if (ast_false(val)) 12062 expungeonhangup = 0; 12063 else 12064 expungeonhangup = 1; 12065 } else { 12066 expungeonhangup = 1; 12067 } 12068 /* IMAP voicemail folder */ 12069 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 12070 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12071 } else { 12072 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12073 } 12074 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12075 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12076 } 12077 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12078 imapgreetings = ast_true(val); 12079 } else { 12080 imapgreetings = 0; 12081 } 12082 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12083 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12084 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12085 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12086 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12087 } else { 12088 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12089 } 12090 12091 /* There is some very unorthodox casting done here. This is due 12092 * to the way c-client handles the argument passed in. It expects a 12093 * void pointer and casts the pointer directly to a long without 12094 * first dereferencing it. */ 12095 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12096 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12097 } else { 12098 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12099 } 12100 12101 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12102 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12103 } else { 12104 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12105 } 12106 12107 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12108 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12109 } else { 12110 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12111 } 12112 12113 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12114 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12115 } else { 12116 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12117 } 12118 12119 /* Increment configuration version */ 12120 imapversion++; 12121 #endif 12122 /* External voicemail notify application */ 12123 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12124 ast_copy_string(externnotify, val, sizeof(externnotify)); 12125 ast_debug(1, "found externnotify: %s\n", externnotify); 12126 } else { 12127 externnotify[0] = '\0'; 12128 } 12129 12130 /* SMDI voicemail notification */ 12131 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12132 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12133 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12134 smdi_iface = ast_smdi_interface_find(val); 12135 } else { 12136 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12137 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12138 } 12139 if (!smdi_iface) { 12140 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12141 } 12142 } 12143 12144 /* Silence treshold */ 12145 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12146 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12147 silencethreshold = atoi(val); 12148 12149 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12150 val = ASTERISK_USERNAME; 12151 ast_copy_string(serveremail, val, sizeof(serveremail)); 12152 12153 vmmaxsecs = 0; 12154 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12155 if (sscanf(val, "%30d", &x) == 1) { 12156 vmmaxsecs = x; 12157 } else { 12158 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12159 } 12160 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12161 static int maxmessage_deprecate = 0; 12162 if (maxmessage_deprecate == 0) { 12163 maxmessage_deprecate = 1; 12164 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12165 } 12166 if (sscanf(val, "%30d", &x) == 1) { 12167 vmmaxsecs = x; 12168 } else { 12169 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12170 } 12171 } 12172 12173 vmminsecs = 0; 12174 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12175 if (sscanf(val, "%30d", &x) == 1) { 12176 vmminsecs = x; 12177 if (maxsilence / 1000 >= vmminsecs) { 12178 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12179 } 12180 } else { 12181 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12182 } 12183 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12184 static int maxmessage_deprecate = 0; 12185 if (maxmessage_deprecate == 0) { 12186 maxmessage_deprecate = 1; 12187 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12188 } 12189 if (sscanf(val, "%30d", &x) == 1) { 12190 vmminsecs = x; 12191 if (maxsilence / 1000 >= vmminsecs) { 12192 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12193 } 12194 } else { 12195 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12196 } 12197 } 12198 12199 val = ast_variable_retrieve(cfg, "general", "format"); 12200 if (!val) { 12201 val = "wav"; 12202 } else { 12203 tmp = ast_strdupa(val); 12204 val = ast_format_str_reduce(tmp); 12205 if (!val) { 12206 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12207 val = "wav"; 12208 } 12209 } 12210 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12211 12212 skipms = 3000; 12213 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12214 if (sscanf(val, "%30d", &x) == 1) { 12215 maxgreet = x; 12216 } else { 12217 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12218 } 12219 } 12220 12221 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12222 if (sscanf(val, "%30d", &x) == 1) { 12223 skipms = x; 12224 } else { 12225 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12226 } 12227 } 12228 12229 maxlogins = 3; 12230 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12231 if (sscanf(val, "%30d", &x) == 1) { 12232 maxlogins = x; 12233 } else { 12234 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12235 } 12236 } 12237 12238 minpassword = MINPASSWORD; 12239 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12240 if (sscanf(val, "%30d", &x) == 1) { 12241 minpassword = x; 12242 } else { 12243 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12244 } 12245 } 12246 12247 /* Force new user to record name ? */ 12248 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12249 val = "no"; 12250 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12251 12252 /* Force new user to record greetings ? */ 12253 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12254 val = "no"; 12255 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12256 12257 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12258 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12259 stringp = ast_strdupa(val); 12260 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12261 if (!ast_strlen_zero(stringp)) { 12262 q = strsep(&stringp, ","); 12263 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12264 q++; 12265 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12266 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12267 } else { 12268 cidinternalcontexts[x][0] = '\0'; 12269 } 12270 } 12271 } 12272 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12273 ast_debug(1, "VM Review Option disabled globally\n"); 12274 val = "no"; 12275 } 12276 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12277 12278 /* Temporary greeting reminder */ 12279 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12280 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12281 val = "no"; 12282 } else { 12283 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12284 } 12285 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12286 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12287 ast_debug(1, "VM next message wrap disabled globally\n"); 12288 val = "no"; 12289 } 12290 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12291 12292 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12293 ast_debug(1, "VM Operator break disabled globally\n"); 12294 val = "no"; 12295 } 12296 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12297 12298 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12299 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12300 val = "no"; 12301 } 12302 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12303 12304 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12305 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12306 val = "no"; 12307 } 12308 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12309 12310 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12311 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12312 val = "yes"; 12313 } 12314 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12315 12316 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12317 ast_debug(1, "Move Heard enabled globally\n"); 12318 val = "yes"; 12319 } 12320 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12321 12322 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12323 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12324 val = "no"; 12325 } 12326 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12327 12328 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12329 ast_debug(1, "Duration info before msg enabled globally\n"); 12330 val = "yes"; 12331 } 12332 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12333 12334 saydurationminfo = 2; 12335 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12336 if (sscanf(val, "%30d", &x) == 1) { 12337 saydurationminfo = x; 12338 } else { 12339 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12340 } 12341 } 12342 12343 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12344 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12345 val = "no"; 12346 } 12347 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12348 12349 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12350 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12351 ast_debug(1, "found dialout context: %s\n", dialcontext); 12352 } else { 12353 dialcontext[0] = '\0'; 12354 } 12355 12356 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12357 ast_copy_string(callcontext, val, sizeof(callcontext)); 12358 ast_debug(1, "found callback context: %s\n", callcontext); 12359 } else { 12360 callcontext[0] = '\0'; 12361 } 12362 12363 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12364 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12365 ast_debug(1, "found operator context: %s\n", exitcontext); 12366 } else { 12367 exitcontext[0] = '\0'; 12368 } 12369 12370 /* load password sounds configuration */ 12371 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12372 ast_copy_string(vm_password, val, sizeof(vm_password)); 12373 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12374 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12375 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12376 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12377 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12378 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12379 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12380 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12381 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12382 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12383 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12384 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12385 } 12386 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12387 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12388 } 12389 /* load configurable audio prompts */ 12390 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12391 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12392 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12393 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12394 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12395 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12396 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12397 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12398 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12399 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12400 12401 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12402 val = "no"; 12403 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12404 12405 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12406 val = "voicemail.conf"; 12407 } 12408 if (!(strcmp(val, "spooldir"))) { 12409 passwordlocation = OPT_PWLOC_SPOOLDIR; 12410 } else { 12411 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12412 } 12413 12414 poll_freq = DEFAULT_POLL_FREQ; 12415 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12416 if (sscanf(val, "%30u", &poll_freq) != 1) { 12417 poll_freq = DEFAULT_POLL_FREQ; 12418 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12419 } 12420 } 12421 12422 poll_mailboxes = 0; 12423 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12424 poll_mailboxes = ast_true(val); 12425 12426 memset(fromstring, 0, sizeof(fromstring)); 12427 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12428 strcpy(charset, "ISO-8859-1"); 12429 if (emailbody) { 12430 ast_free(emailbody); 12431 emailbody = NULL; 12432 } 12433 if (emailsubject) { 12434 ast_free(emailsubject); 12435 emailsubject = NULL; 12436 } 12437 if (pagerbody) { 12438 ast_free(pagerbody); 12439 pagerbody = NULL; 12440 } 12441 if (pagersubject) { 12442 ast_free(pagersubject); 12443 pagersubject = NULL; 12444 } 12445 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12446 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12447 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12448 ast_copy_string(fromstring, val, sizeof(fromstring)); 12449 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12450 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12451 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12452 ast_copy_string(charset, val, sizeof(charset)); 12453 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12454 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12455 for (x = 0; x < 4; x++) { 12456 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12457 } 12458 } 12459 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12460 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12461 for (x = 0; x < 4; x++) { 12462 memcpy(&adsisec[x], &tmpadsi[x], 1); 12463 } 12464 } 12465 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12466 if (atoi(val)) { 12467 adsiver = atoi(val); 12468 } 12469 } 12470 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12471 ast_copy_string(zonetag, val, sizeof(zonetag)); 12472 } 12473 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12474 ast_copy_string(locale, val, sizeof(locale)); 12475 } 12476 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12477 emailsubject = ast_strdup(substitute_escapes(val)); 12478 } 12479 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12480 emailbody = ast_strdup(substitute_escapes(val)); 12481 } 12482 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12483 pagersubject = ast_strdup(substitute_escapes(val)); 12484 } 12485 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12486 pagerbody = ast_strdup(substitute_escapes(val)); 12487 } 12488 12489 /* load mailboxes from users.conf */ 12490 if (ucfg) { 12491 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12492 if (!strcasecmp(cat, "general")) { 12493 continue; 12494 } 12495 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12496 continue; 12497 if ((current = find_or_create(userscontext, cat))) { 12498 populate_defaults(current); 12499 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12500 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12501 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12502 current->passwordlocation = OPT_PWLOC_USERSCONF; 12503 } 12504 12505 switch (current->passwordlocation) { 12506 case OPT_PWLOC_SPOOLDIR: 12507 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12508 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12509 } 12510 } 12511 } 12512 } 12513 12514 /* load mailboxes from voicemail.conf */ 12515 cat = ast_category_browse(cfg, NULL); 12516 while (cat) { 12517 if (strcasecmp(cat, "general")) { 12518 var = ast_variable_browse(cfg, cat); 12519 if (strcasecmp(cat, "zonemessages")) { 12520 /* Process mailboxes in this context */ 12521 while (var) { 12522 append_mailbox(cat, var->name, var->value); 12523 var = var->next; 12524 } 12525 } else { 12526 /* Timezones in this context */ 12527 while (var) { 12528 struct vm_zone *z; 12529 if ((z = ast_malloc(sizeof(*z)))) { 12530 char *msg_format, *tzone; 12531 msg_format = ast_strdupa(var->value); 12532 tzone = strsep(&msg_format, "|,"); 12533 if (msg_format) { 12534 ast_copy_string(z->name, var->name, sizeof(z->name)); 12535 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12536 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12537 AST_LIST_LOCK(&zones); 12538 AST_LIST_INSERT_HEAD(&zones, z, list); 12539 AST_LIST_UNLOCK(&zones); 12540 } else { 12541 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12542 ast_free(z); 12543 } 12544 } else { 12545 AST_LIST_UNLOCK(&users); 12546 return -1; 12547 } 12548 var = var->next; 12549 } 12550 } 12551 } 12552 cat = ast_category_browse(cfg, cat); 12553 } 12554 12555 AST_LIST_UNLOCK(&users); 12556 12557 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12558 start_poll_thread(); 12559 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12560 stop_poll_thread();; 12561 12562 return 0; 12563 } else { 12564 AST_LIST_UNLOCK(&users); 12565 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12566 return 0; 12567 } 12568 }
| 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 4823 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().
04824 { 04825 char tmpdir[256], newtmp[256]; 04826 char fname[256]; 04827 char tmpcmd[256]; 04828 int tmpfd = -1; 04829 int soxstatus = 0; 04830 04831 /* Eww. We want formats to tell us their own MIME type */ 04832 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04833 04834 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04835 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04836 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04837 tmpfd = mkstemp(newtmp); 04838 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04839 ast_debug(3, "newtmp: %s\n", newtmp); 04840 if (tmpfd > -1) { 04841 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04842 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04843 attach = newtmp; 04844 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04845 } else { 04846 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04847 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04848 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04849 } 04850 } 04851 } 04852 fprintf(p, "--%s" ENDL, bound); 04853 if (msgnum > -1) 04854 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04855 else 04856 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04857 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04858 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04859 if (msgnum > -1) 04860 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04861 else 04862 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04863 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04864 base_encode(fname, p); 04865 if (last) 04866 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04867 if (tmpfd > -1) { 04868 if (soxstatus == 0) { 04869 unlink(fname); 04870 } 04871 close(tmpfd); 04872 unlink(newtmp); 04873 } 04874 return 0; 04875 }
| static void adsi_begin | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 6432 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().
06433 { 06434 int x; 06435 if (!ast_adsi_available(chan)) 06436 return; 06437 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06438 if (x < 0) 06439 return; 06440 if (!x) { 06441 if (adsi_load_vmail(chan, useadsi)) { 06442 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06443 return; 06444 } 06445 } else 06446 *useadsi = 1; 06447 }
| static void adsi_delete | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6627 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().
06628 { 06629 int bytes = 0; 06630 unsigned char buf[256]; 06631 unsigned char keys[8]; 06632 06633 int x; 06634 06635 if (!ast_adsi_available(chan)) 06636 return; 06637 06638 /* New meaning for keys */ 06639 for (x = 0; x < 5; x++) 06640 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06641 06642 keys[6] = 0x0; 06643 keys[7] = 0x0; 06644 06645 if (!vms->curmsg) { 06646 /* No prev key, provide "Folder" instead */ 06647 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06648 } 06649 if (vms->curmsg >= vms->lastmsg) { 06650 /* If last message ... */ 06651 if (vms->curmsg) { 06652 /* but not only message, provide "Folder" instead */ 06653 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06654 } else { 06655 /* Otherwise if only message, leave blank */ 06656 keys[3] = 1; 06657 } 06658 } 06659 06660 /* If deleted, show "undeleted" */ 06661 #ifdef IMAP_STORAGE 06662 ast_mutex_lock(&vms->lock); 06663 #endif 06664 if (vms->deleted[vms->curmsg]) { 06665 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06666 } 06667 #ifdef IMAP_STORAGE 06668 ast_mutex_unlock(&vms->lock); 06669 #endif 06670 06671 /* Except "Exit" */ 06672 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06673 bytes += ast_adsi_set_keys(buf + bytes, keys); 06674 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06675 06676 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06677 }
| static void adsi_folders | ( | struct ast_channel * | chan, | |
| int | start, | |||
| char * | label | |||
| ) | [static] |
Definition at line 6497 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().
06498 { 06499 unsigned char buf[256]; 06500 int bytes = 0; 06501 unsigned char keys[8]; 06502 int x, y; 06503 06504 if (!ast_adsi_available(chan)) 06505 return; 06506 06507 for (x = 0; x < 5; x++) { 06508 y = ADSI_KEY_APPS + 12 + start + x; 06509 if (y > ADSI_KEY_APPS + 12 + 4) 06510 y = 0; 06511 keys[x] = ADSI_KEY_SKT | y; 06512 } 06513 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06514 keys[6] = 0; 06515 keys[7] = 0; 06516 06517 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06518 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06519 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06520 bytes += ast_adsi_set_keys(buf + bytes, keys); 06521 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06522 06523 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06524 }
| static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6782 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().
06783 { 06784 unsigned char buf[256]; 06785 int bytes = 0; 06786 06787 if (!ast_adsi_available(chan)) 06788 return; 06789 bytes += adsi_logo(buf + bytes); 06790 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06791 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06792 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06793 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06794 06795 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06796 }
| static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 6303 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().
06304 { 06305 unsigned char buf[256]; 06306 int bytes = 0; 06307 int x; 06308 char num[5]; 06309 06310 *useadsi = 0; 06311 bytes += ast_adsi_data_mode(buf + bytes); 06312 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06313 06314 bytes = 0; 06315 bytes += adsi_logo(buf); 06316 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06317 #ifdef DISPLAY 06318 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06319 #endif 06320 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06321 bytes += ast_adsi_data_mode(buf + bytes); 06322 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06323 06324 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06325 bytes = 0; 06326 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06327 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06328 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06329 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06330 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06331 return 0; 06332 } 06333 06334 #ifdef DISPLAY 06335 /* Add a dot */ 06336 bytes = 0; 06337 bytes += ast_adsi_logo(buf); 06338 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06339 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06340 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06341 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06342 #endif 06343 bytes = 0; 06344 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06345 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06346 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06347 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06348 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06349 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06350 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06351 06352 #ifdef DISPLAY 06353 /* Add another dot */ 06354 bytes = 0; 06355 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06356 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06357 06358 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06359 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06360 #endif 06361 06362 bytes = 0; 06363 /* These buttons we load but don't use yet */ 06364 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06365 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06366 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06367 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06368 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06369 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06370 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06371 06372 #ifdef DISPLAY 06373 /* Add another dot */ 06374 bytes = 0; 06375 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06376 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06377 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06378 #endif 06379 06380 bytes = 0; 06381 for (x = 0; x < 5; x++) { 06382 snprintf(num, sizeof(num), "%d", x); 06383 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06384 } 06385 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06386 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06387 06388 #ifdef DISPLAY 06389 /* Add another dot */ 06390 bytes = 0; 06391 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06392 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06393 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06394 #endif 06395 06396 if (ast_adsi_end_download(chan)) { 06397 bytes = 0; 06398 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06399 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06400 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06401 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06402 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06403 return 0; 06404 } 06405 bytes = 0; 06406 bytes += ast_adsi_download_disconnect(buf + bytes); 06407 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06408 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06409 06410 ast_debug(1, "Done downloading scripts...\n"); 06411 06412 #ifdef DISPLAY 06413 /* Add last dot */ 06414 bytes = 0; 06415 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06416 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06417 #endif 06418 ast_debug(1, "Restarting session...\n"); 06419 06420 bytes = 0; 06421 /* Load the session now */ 06422 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06423 *useadsi = 1; 06424 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06425 } else 06426 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06427 06428 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06429 return 0; 06430 }
| static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6449 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().
06450 { 06451 unsigned char buf[256]; 06452 int bytes = 0; 06453 unsigned char keys[8]; 06454 int x; 06455 if (!ast_adsi_available(chan)) 06456 return; 06457 06458 for (x = 0; x < 8; x++) 06459 keys[x] = 0; 06460 /* Set one key for next */ 06461 keys[3] = ADSI_KEY_APPS + 3; 06462 06463 bytes += adsi_logo(buf + bytes); 06464 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06465 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06466 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06467 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06468 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06469 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06470 bytes += ast_adsi_set_keys(buf + bytes, keys); 06471 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06472 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06473 }
| static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6295 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().
06296 { 06297 int bytes = 0; 06298 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06299 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06300 return bytes; 06301 }
| static void adsi_message | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6526 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().
06527 { 06528 int bytes = 0; 06529 unsigned char buf[256]; 06530 char buf1[256], buf2[256]; 06531 char fn2[PATH_MAX]; 06532 06533 char cid[256] = ""; 06534 char *val; 06535 char *name, *num; 06536 char datetime[21] = ""; 06537 FILE *f; 06538 06539 unsigned char keys[8]; 06540 06541 int x; 06542 06543 if (!ast_adsi_available(chan)) 06544 return; 06545 06546 /* Retrieve important info */ 06547 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06548 f = fopen(fn2, "r"); 06549 if (f) { 06550 while (!feof(f)) { 06551 if (!fgets((char *) buf, sizeof(buf), f)) { 06552 continue; 06553 } 06554 if (!feof(f)) { 06555 char *stringp = NULL; 06556 stringp = (char *) buf; 06557 strsep(&stringp, "="); 06558 val = strsep(&stringp, "="); 06559 if (!ast_strlen_zero(val)) { 06560 if (!strcmp((char *) buf, "callerid")) 06561 ast_copy_string(cid, val, sizeof(cid)); 06562 if (!strcmp((char *) buf, "origdate")) 06563 ast_copy_string(datetime, val, sizeof(datetime)); 06564 } 06565 } 06566 } 06567 fclose(f); 06568 } 06569 /* New meaning for keys */ 06570 for (x = 0; x < 5; x++) 06571 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06572 keys[6] = 0x0; 06573 keys[7] = 0x0; 06574 06575 if (!vms->curmsg) { 06576 /* No prev key, provide "Folder" instead */ 06577 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06578 } 06579 if (vms->curmsg >= vms->lastmsg) { 06580 /* If last message ... */ 06581 if (vms->curmsg) { 06582 /* but not only message, provide "Folder" instead */ 06583 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06584 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06585 06586 } else { 06587 /* Otherwise if only message, leave blank */ 06588 keys[3] = 1; 06589 } 06590 } 06591 06592 if (!ast_strlen_zero(cid)) { 06593 ast_callerid_parse(cid, &name, &num); 06594 if (!name) 06595 name = num; 06596 } else 06597 name = "Unknown Caller"; 06598 06599 /* If deleted, show "undeleted" */ 06600 #ifdef IMAP_STORAGE 06601 ast_mutex_lock(&vms->lock); 06602 #endif 06603 if (vms->deleted[vms->curmsg]) { 06604 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06605 } 06606 #ifdef IMAP_STORAGE 06607 ast_mutex_unlock(&vms->lock); 06608 #endif 06609 06610 /* Except "Exit" */ 06611 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06612 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06613 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06614 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06615 06616 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06617 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06618 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06619 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06620 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06621 bytes += ast_adsi_set_keys(buf + bytes, keys); 06622 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06623 06624 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06625 }
| static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6475 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().
06476 { 06477 unsigned char buf[256]; 06478 int bytes = 0; 06479 unsigned char keys[8]; 06480 int x; 06481 if (!ast_adsi_available(chan)) 06482 return; 06483 06484 for (x = 0; x < 8; x++) 06485 keys[x] = 0; 06486 /* Set one key for next */ 06487 keys[3] = ADSI_KEY_APPS + 3; 06488 06489 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06490 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06491 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06492 bytes += ast_adsi_set_keys(buf + bytes, keys); 06493 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06494 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06495 }
| static void adsi_status | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6679 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().
06680 { 06681 unsigned char buf[256] = ""; 06682 char buf1[256] = "", buf2[256] = ""; 06683 int bytes = 0; 06684 unsigned char keys[8]; 06685 int x; 06686 06687 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06688 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06689 if (!ast_adsi_available(chan)) 06690 return; 06691 if (vms->newmessages) { 06692 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06693 if (vms->oldmessages) { 06694 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06695 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06696 } else { 06697 snprintf(buf2, sizeof(buf2), "%s.", newm); 06698 } 06699 } else if (vms->oldmessages) { 06700 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06701 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06702 } else { 06703 strcpy(buf1, "You have no messages."); 06704 buf2[0] = ' '; 06705 buf2[1] = '\0'; 06706 } 06707 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06708 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06709 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06710 06711 for (x = 0; x < 6; x++) 06712 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06713 keys[6] = 0; 06714 keys[7] = 0; 06715 06716 /* Don't let them listen if there are none */ 06717 if (vms->lastmsg < 0) 06718 keys[0] = 1; 06719 bytes += ast_adsi_set_keys(buf + bytes, keys); 06720 06721 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06722 06723 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06724 }
| static void adsi_status2 | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6726 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().
06727 { 06728 unsigned char buf[256] = ""; 06729 char buf1[256] = "", buf2[256] = ""; 06730 int bytes = 0; 06731 unsigned char keys[8]; 06732 int x; 06733 06734 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06735 06736 if (!ast_adsi_available(chan)) 06737 return; 06738 06739 /* Original command keys */ 06740 for (x = 0; x < 6; x++) 06741 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06742 06743 keys[6] = 0; 06744 keys[7] = 0; 06745 06746 if ((vms->lastmsg + 1) < 1) 06747 keys[0] = 0; 06748 06749 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06750 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06751 06752 if (vms->lastmsg + 1) 06753 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06754 else 06755 strcpy(buf2, "no messages."); 06756 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06757 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06758 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06759 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06760 bytes += ast_adsi_set_keys(buf + bytes, keys); 06761 06762 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06763 06764 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06765 06766 }
| 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 13276 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().
13277 { 13278 int res = 0; 13279 char filename[PATH_MAX]; 13280 struct ast_config *msg_cfg = NULL; 13281 const char *origtime, *context; 13282 char *name, *num; 13283 int retries = 0; 13284 char *cid; 13285 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13286 13287 vms->starting = 0; 13288 13289 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13290 13291 /* Retrieve info from VM attribute file */ 13292 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13293 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13294 msg_cfg = ast_config_load(filename, config_flags); 13295 DISPOSE(vms->curdir, vms->curmsg); 13296 if (!valid_config(msg_cfg)) { 13297 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13298 return 0; 13299 } 13300 13301 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13302 ast_config_destroy(msg_cfg); 13303 return 0; 13304 } 13305 13306 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13307 13308 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13309 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13310 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13311 switch (option) { 13312 case 3: /* Play message envelope */ 13313 if (!res) 13314 res = play_message_datetime(chan, vmu, origtime, filename); 13315 if (!res) 13316 res = play_message_callerid(chan, vms, cid, context, 0); 13317 13318 res = 't'; 13319 break; 13320 13321 case 2: /* Call back */ 13322 13323 if (ast_strlen_zero(cid)) 13324 break; 13325 13326 ast_callerid_parse(cid, &name, &num); 13327 while ((res > -1) && (res != 't')) { 13328 switch (res) { 13329 case '1': 13330 if (num) { 13331 /* Dial the CID number */ 13332 res = dialout(chan, vmu, num, vmu->callback); 13333 if (res) { 13334 ast_config_destroy(msg_cfg); 13335 return 9; 13336 } 13337 } else { 13338 res = '2'; 13339 } 13340 break; 13341 13342 case '2': 13343 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13344 if (!ast_strlen_zero(vmu->dialout)) { 13345 res = dialout(chan, vmu, NULL, vmu->dialout); 13346 if (res) { 13347 ast_config_destroy(msg_cfg); 13348 return 9; 13349 } 13350 } else { 13351 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13352 res = ast_play_and_wait(chan, "vm-sorry"); 13353 } 13354 ast_config_destroy(msg_cfg); 13355 return res; 13356 case '*': 13357 res = 't'; 13358 break; 13359 case '3': 13360 case '4': 13361 case '5': 13362 case '6': 13363 case '7': 13364 case '8': 13365 case '9': 13366 case '0': 13367 13368 res = ast_play_and_wait(chan, "vm-sorry"); 13369 retries++; 13370 break; 13371 default: 13372 if (num) { 13373 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13374 res = ast_play_and_wait(chan, "vm-num-i-have"); 13375 if (!res) 13376 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13377 if (!res) 13378 res = ast_play_and_wait(chan, "vm-tocallnum"); 13379 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13380 if (!ast_strlen_zero(vmu->dialout)) { 13381 if (!res) 13382 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13383 } 13384 } else { 13385 res = ast_play_and_wait(chan, "vm-nonumber"); 13386 if (!ast_strlen_zero(vmu->dialout)) { 13387 if (!res) 13388 res = ast_play_and_wait(chan, "vm-toenternumber"); 13389 } 13390 } 13391 if (!res) { 13392 res = ast_play_and_wait(chan, "vm-star-cancel"); 13393 } 13394 if (!res) { 13395 res = ast_waitfordigit(chan, 6000); 13396 } 13397 if (!res) { 13398 retries++; 13399 if (retries > 3) { 13400 res = 't'; 13401 } 13402 } 13403 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13404 break; 13405 13406 } 13407 if (res == 't') 13408 res = 0; 13409 else if (res == '*') 13410 res = -1; 13411 } 13412 break; 13413 13414 case 1: /* Reply */ 13415 /* Send reply directly to sender */ 13416 if (ast_strlen_zero(cid)) 13417 break; 13418 13419 ast_callerid_parse(cid, &name, &num); 13420 if (!num) { 13421 ast_verb(3, "No CID number available, no reply sent\n"); 13422 if (!res) 13423 res = ast_play_and_wait(chan, "vm-nonumber"); 13424 ast_config_destroy(msg_cfg); 13425 return res; 13426 } else { 13427 struct ast_vm_user vmu2; 13428 if (find_user(&vmu2, vmu->context, num)) { 13429 struct leave_vm_options leave_options; 13430 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13431 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13432 13433 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13434 13435 memset(&leave_options, 0, sizeof(leave_options)); 13436 leave_options.record_gain = record_gain; 13437 res = leave_voicemail(chan, mailbox, &leave_options); 13438 if (!res) 13439 res = 't'; 13440 ast_config_destroy(msg_cfg); 13441 return res; 13442 } else { 13443 /* Sender has no mailbox, can't reply */ 13444 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13445 ast_play_and_wait(chan, "vm-nobox"); 13446 res = 't'; 13447 ast_config_destroy(msg_cfg); 13448 return res; 13449 } 13450 } 13451 res = 0; 13452 13453 break; 13454 } 13455 13456 ast_config_destroy(msg_cfg); 13457 13458 #ifndef IMAP_STORAGE 13459 if (!res) { 13460 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13461 vms->heard[msg] = 1; 13462 res = wait_file(chan, vms, vms->fn); 13463 } 13464 #endif 13465 return res; 13466 }
| static int append_mailbox | ( | const char * | context, | |
| const char * | box, | |||
| const char * | data | |||
| ) | [static] |
Definition at line 10797 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().
10798 { 10799 /* Assumes lock is already held */ 10800 char *tmp; 10801 char *stringp; 10802 char *s; 10803 struct ast_vm_user *vmu; 10804 char *mailbox_full; 10805 int new = 0, old = 0, urgent = 0; 10806 char secretfn[PATH_MAX] = ""; 10807 10808 tmp = ast_strdupa(data); 10809 10810 if (!(vmu = find_or_create(context, box))) 10811 return -1; 10812 10813 populate_defaults(vmu); 10814 10815 stringp = tmp; 10816 if ((s = strsep(&stringp, ","))) { 10817 if (!ast_strlen_zero(s) && s[0] == '*') { 10818 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10819 "\n\tmust be reset in voicemail.conf.\n", box); 10820 } 10821 /* assign password regardless of validity to prevent NULL password from being assigned */ 10822 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10823 } 10824 if (stringp && (s = strsep(&stringp, ","))) { 10825 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10826 } 10827 if (stringp && (s = strsep(&stringp, ","))) { 10828 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10829 } 10830 if (stringp && (s = strsep(&stringp, ","))) { 10831 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10832 } 10833 if (stringp && (s = strsep(&stringp, ","))) { 10834 apply_options(vmu, s); 10835 } 10836 10837 switch (vmu->passwordlocation) { 10838 case OPT_PWLOC_SPOOLDIR: 10839 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10840 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10841 } 10842 10843 mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1); 10844 strcpy(mailbox_full, box); 10845 strcat(mailbox_full, "@"); 10846 strcat(mailbox_full, context); 10847 10848 inboxcount2(mailbox_full, &urgent, &new, &old); 10849 queue_mwi_event(mailbox_full, urgent, new, old); 10850 10851 return 0; 10852 }
| 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 1063 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().
01064 { 01065 int x; 01066 if (!strcasecmp(var, "attach")) { 01067 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01068 } else if (!strcasecmp(var, "attachfmt")) { 01069 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01070 } else if (!strcasecmp(var, "serveremail")) { 01071 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01072 } else if (!strcasecmp(var, "emailbody")) { 01073 vmu->emailbody = ast_strdup(substitute_escapes(value)); 01074 } else if (!strcasecmp(var, "emailsubject")) { 01075 vmu->emailsubject = ast_strdup(substitute_escapes(value)); 01076 } else if (!strcasecmp(var, "language")) { 01077 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01078 } else if (!strcasecmp(var, "tz")) { 01079 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01080 } else if (!strcasecmp(var, "locale")) { 01081 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01082 #ifdef IMAP_STORAGE 01083 } else if (!strcasecmp(var, "imapuser")) { 01084 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01085 vmu->imapversion = imapversion; 01086 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01087 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01088 vmu->imapversion = imapversion; 01089 } else if (!strcasecmp(var, "imapfolder")) { 01090 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01091 } else if (!strcasecmp(var, "imapvmshareid")) { 01092 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01093 vmu->imapversion = imapversion; 01094 #endif 01095 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01096 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01097 } else if (!strcasecmp(var, "saycid")){ 01098 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01099 } else if (!strcasecmp(var, "sendvoicemail")){ 01100 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01101 } else if (!strcasecmp(var, "review")){ 01102 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01103 } else if (!strcasecmp(var, "tempgreetwarn")){ 01104 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01105 } else if (!strcasecmp(var, "messagewrap")){ 01106 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01107 } else if (!strcasecmp(var, "operator")) { 01108 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01109 } else if (!strcasecmp(var, "envelope")){ 01110 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01111 } else if (!strcasecmp(var, "moveheard")){ 01112 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01113 } else if (!strcasecmp(var, "sayduration")){ 01114 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01115 } else if (!strcasecmp(var, "saydurationm")){ 01116 if (sscanf(value, "%30d", &x) == 1) { 01117 vmu->saydurationm = x; 01118 } else { 01119 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01120 } 01121 } else if (!strcasecmp(var, "forcename")){ 01122 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01123 } else if (!strcasecmp(var, "forcegreetings")){ 01124 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01125 } else if (!strcasecmp(var, "callback")) { 01126 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01127 } else if (!strcasecmp(var, "dialout")) { 01128 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01129 } else if (!strcasecmp(var, "exitcontext")) { 01130 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01131 } else if (!strcasecmp(var, "minsecs")) { 01132 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01133 vmu->minsecs = x; 01134 } else { 01135 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01136 vmu->minsecs = vmminsecs; 01137 } 01138 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01139 vmu->maxsecs = atoi(value); 01140 if (vmu->maxsecs <= 0) { 01141 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01142 vmu->maxsecs = vmmaxsecs; 01143 } else { 01144 vmu->maxsecs = atoi(value); 01145 } 01146 if (!strcasecmp(var, "maxmessage")) 01147 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01148 } else if (!strcasecmp(var, "maxmsg")) { 01149 vmu->maxmsg = atoi(value); 01150 /* Accept maxmsg=0 (Greetings only voicemail) */ 01151 if (vmu->maxmsg < 0) { 01152 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01153 vmu->maxmsg = MAXMSG; 01154 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01155 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01156 vmu->maxmsg = MAXMSGLIMIT; 01157 } 01158 } else if (!strcasecmp(var, "nextaftercmd")) { 01159 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01160 } else if (!strcasecmp(var, "backupdeleted")) { 01161 if (sscanf(value, "%30d", &x) == 1) 01162 vmu->maxdeletedmsg = x; 01163 else if (ast_true(value)) 01164 vmu->maxdeletedmsg = MAXMSG; 01165 else 01166 vmu->maxdeletedmsg = 0; 01167 01168 if (vmu->maxdeletedmsg < 0) { 01169 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01170 vmu->maxdeletedmsg = MAXMSG; 01171 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01172 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01173 vmu->maxdeletedmsg = MAXMSGLIMIT; 01174 } 01175 } else if (!strcasecmp(var, "volgain")) { 01176 sscanf(value, "%30lf", &vmu->volgain); 01177 } else if (!strcasecmp(var, "passwordlocation")) { 01178 if (!strcasecmp(value, "spooldir")) { 01179 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01180 } else { 01181 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01182 } 01183 } else if (!strcasecmp(var, "options")) { 01184 apply_options(vmu, value); 01185 } 01186 }
| static void apply_options | ( | struct ast_vm_user * | vmu, | |
| const char * | options | |||
| ) | [static] |
Destructively Parse options and apply.
Definition at line 1304 of file app_voicemail.c.
References apply_option(), ast_strdupa, value, and var.
Referenced by append_mailbox(), apply_option(), and AST_TEST_DEFINE().
01305 { 01306 char *stringp; 01307 char *s; 01308 char *var, *value; 01309 stringp = ast_strdupa(options); 01310 while ((s = strsep(&stringp, "|"))) { 01311 value = s; 01312 if ((var = strsep(&value, "=")) && value) { 01313 apply_option(vmu, var, value); 01314 } 01315 } 01316 }
| 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 1323 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().
01324 { 01325 for (; var; var = var->next) { 01326 if (!strcasecmp(var->name, "vmsecret")) { 01327 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01328 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01329 if (ast_strlen_zero(retval->password)) { 01330 if (!ast_strlen_zero(var->value) && var->value[0] == '*') { 01331 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 01332 "\n\tmust be reset in voicemail.conf.\n", retval->mailbox); 01333 } else { 01334 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01335 } 01336 } 01337 } else if (!strcasecmp(var->name, "uniqueid")) { 01338 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01339 } else if (!strcasecmp(var->name, "pager")) { 01340 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01341 } else if (!strcasecmp(var->name, "email")) { 01342 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01343 } else if (!strcasecmp(var->name, "fullname")) { 01344 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01345 } else if (!strcasecmp(var->name, "context")) { 01346 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01347 } else if (!strcasecmp(var->name, "emailsubject")) { 01348 ast_free(retval->emailsubject); 01349 retval->emailsubject = ast_strdup(substitute_escapes(var->value)); 01350 } else if (!strcasecmp(var->name, "emailbody")) { 01351 ast_free(retval->emailbody); 01352 retval->emailbody = ast_strdup(substitute_escapes(var->value)); 01353 #ifdef IMAP_STORAGE 01354 } else if (!strcasecmp(var->name, "imapuser")) { 01355 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01356 retval->imapversion = imapversion; 01357 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01358 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01359 retval->imapversion = imapversion; 01360 } else if (!strcasecmp(var->name, "imapfolder")) { 01361 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01362 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01363 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01364 retval->imapversion = imapversion; 01365 #endif 01366 } else 01367 apply_option(retval, var->name, var->value); 01368 } 01369 }
| 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 4498 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().
04499 { 04500 struct ast_str *tmp = ast_str_alloca(80); 04501 int first_section = 1; 04502 04503 ast_str_reset(*end); 04504 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04505 for (; *start; start++) { 04506 int need_encoding = 0; 04507 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04508 need_encoding = 1; 04509 } 04510 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04511 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04512 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04513 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04514 /* Start new line */ 04515 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04516 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04517 first_section = 0; 04518 } 04519 if (need_encoding && *start == ' ') { 04520 ast_str_append(&tmp, -1, "_"); 04521 } else if (need_encoding) { 04522 ast_str_append(&tmp, -1, "=%hhX", *start); 04523 } else { 04524 ast_str_append(&tmp, -1, "%c", *start); 04525 } 04526 } 04527 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04528 return ast_str_buffer(*end); 04529 }
| 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 4426 of file app_voicemail.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
Referenced by make_email_file(), and sendpage().
04427 { 04428 const char *ptr; 04429 04430 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04431 ast_str_set(buf, maxlen, "\""); 04432 for (ptr = from; *ptr; ptr++) { 04433 if (*ptr == '"' || *ptr == '\\') { 04434 ast_str_append(buf, maxlen, "\\%c", *ptr); 04435 } else { 04436 ast_str_append(buf, maxlen, "%c", *ptr); 04437 } 04438 } 04439 ast_str_append(buf, maxlen, "\""); 04440 04441 return ast_str_buffer(*buf); 04442 }
| AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10854 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.
10855 { 10856 int res = 0; 10857 struct ast_vm_user *vmu; 10858 /* language parameter seems to only be used for display in manager action */ 10859 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10860 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10861 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10862 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10863 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10864 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10865 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10866 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10867 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10868 #ifdef IMAP_STORAGE 10869 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10870 "imapfolder=INBOX|imapvmshareid=6000"; 10871 #endif 10872 10873 switch (cmd) { 10874 case TEST_INIT: 10875 info->name = "vmuser"; 10876 info->category = "/apps/app_voicemail/"; 10877 info->summary = "Vmuser unit test"; 10878 info->description = 10879 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10880 return AST_TEST_NOT_RUN; 10881 case TEST_EXECUTE: 10882 break; 10883 } 10884 10885 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10886 return AST_TEST_NOT_RUN; 10887 } 10888 populate_defaults(vmu); 10889 ast_set_flag(vmu, VM_ALLOCED); 10890 10891 apply_options(vmu, options_string); 10892 10893 if (!ast_test_flag(vmu, VM_ATTACH)) { 10894 ast_test_status_update(test, "Parse failure for attach option\n"); 10895 res = 1; 10896 } 10897 if (strcasecmp(vmu->attachfmt, "wav49")) { 10898 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10899 res = 1; 10900 } 10901 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10902 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10903 res = 1; 10904 } 10905 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10906 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10907 res = 1; 10908 } 10909 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10910 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10911 res = 1; 10912 } 10913 if (strcasecmp(vmu->zonetag, "central")) { 10914 ast_test_status_update(test, "Parse failure for tz option\n"); 10915 res = 1; 10916 } 10917 if (!ast_test_flag(vmu, VM_DELETE)) { 10918 ast_test_status_update(test, "Parse failure for delete option\n"); 10919 res = 1; 10920 } 10921 if (!ast_test_flag(vmu, VM_SAYCID)) { 10922 ast_test_status_update(test, "Parse failure for saycid option\n"); 10923 res = 1; 10924 } 10925 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10926 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10927 res = 1; 10928 } 10929 if (!ast_test_flag(vmu, VM_REVIEW)) { 10930 ast_test_status_update(test, "Parse failure for review option\n"); 10931 res = 1; 10932 } 10933 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10934 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10935 res = 1; 10936 } 10937 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10938 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10939 res = 1; 10940 } 10941 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10942 ast_test_status_update(test, "Parse failure for operator option\n"); 10943 res = 1; 10944 } 10945 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10946 ast_test_status_update(test, "Parse failure for envelope option\n"); 10947 res = 1; 10948 } 10949 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10950 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10951 res = 1; 10952 } 10953 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10954 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10955 res = 1; 10956 } 10957 if (vmu->saydurationm != 5) { 10958 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10959 res = 1; 10960 } 10961 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10962 ast_test_status_update(test, "Parse failure for forcename option\n"); 10963 res = 1; 10964 } 10965 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10966 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10967 res = 1; 10968 } 10969 if (strcasecmp(vmu->callback, "somecontext")) { 10970 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10971 res = 1; 10972 } 10973 if (strcasecmp(vmu->dialout, "somecontext2")) { 10974 ast_test_status_update(test, "Parse failure for dialout option\n"); 10975 res = 1; 10976 } 10977 if (strcasecmp(vmu->exit, "somecontext3")) { 10978 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10979 res = 1; 10980 } 10981 if (vmu->minsecs != 10) { 10982 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10983 res = 1; 10984 } 10985 if (vmu->maxsecs != 100) { 10986 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10987 res = 1; 10988 } 10989 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10990 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10991 res = 1; 10992 } 10993 if (vmu->maxdeletedmsg != 50) { 10994 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10995 res = 1; 10996 } 10997 if (vmu->volgain != 1.3) { 10998 ast_test_status_update(test, "Parse failure for volgain option\n"); 10999 res = 1; 11000 } 11001 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 11002 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 11003 res = 1; 11004 } 11005 #ifdef IMAP_STORAGE 11006 apply_options(vmu, option_string2); 11007 11008 if (strcasecmp(vmu->imapuser, "imapuser")) { 11009 ast_test_status_update(test, "Parse failure for imapuser option\n"); 11010 res = 1; 11011 } 11012 if (strcasecmp(vmu->imappassword, "imappasswd")) { 11013 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 11014 res = 1; 11015 } 11016 if (strcasecmp(vmu->imapfolder, "INBOX")) { 11017 ast_test_status_update(test, "Parse failure for imapfolder option\n"); 11018 res = 1; 11019 } 11020 if (strcasecmp(vmu->imapvmshareid, "6000")) { 11021 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 11022 res = 1; 11023 } 11024 #endif 11025 11026 free_user(vmu); 11027 return res ? AST_TEST_FAIL : AST_TEST_PASS; 11028 }
| 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 4302 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, BASEMAXINLINE, ENDL, errno, inchar(), baseio::iocp, and ochar().
Referenced by add_email_attachment().
04303 { 04304 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04305 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04306 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04307 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04308 int i, hiteof = 0; 04309 FILE *fi; 04310 struct baseio bio; 04311 04312 memset(&bio, 0, sizeof(bio)); 04313 bio.iocp = BASEMAXINLINE; 04314 04315 if (!(fi = fopen(filename, "rb"))) { 04316 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04317 return -1; 04318 } 04319 04320 while (!hiteof){ 04321 unsigned char igroup[3], ogroup[4]; 04322 int c, n; 04323 04324 memset(igroup, 0, sizeof(igroup)); 04325 04326 for (n = 0; n < 3; n++) { 04327 if ((c = inchar(&bio, fi)) == EOF) { 04328 hiteof = 1; 04329 break; 04330 } 04331 04332 igroup[n] = (unsigned char) c; 04333 } 04334 04335 if (n > 0) { 04336 ogroup[0]= dtable[igroup[0] >> 2]; 04337 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04338 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04339 ogroup[3]= dtable[igroup[2] & 0x3F]; 04340 04341 if (n < 3) { 04342 ogroup[3] = '='; 04343 04344 if (n < 2) 04345 ogroup[2] = '='; 04346 } 04347 04348 for (i = 0; i < 4; i++) 04349 ochar(&bio, ogroup[i], so); 04350 } 04351 } 04352 04353 fclose(fi); 04354 04355 if (fputs(ENDL, so) == EOF) { 04356 return 0; 04357 } 04358 04359 return 1; 04360 }
| 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 1282 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().
01283 { 01284 int res = -1; 01285 if (!strcmp(vmu->password, password)) { 01286 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01287 return 0; 01288 } 01289 01290 if (strlen(password) > 10) { 01291 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01292 } 01293 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01294 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime"); 01295 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01296 res = 0; 01297 } 01298 return res; 01299 }
| 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 4471 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 1241 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().
01242 { 01243 /* check minimum length */ 01244 if (strlen(password) < minpassword) 01245 return 1; 01246 /* check that password does not contain '*' character */ 01247 if (!ast_strlen_zero(password) && password[0] == '*') 01248 return 1; 01249 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01250 char cmd[255], buf[255]; 01251 01252 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01253 01254 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01255 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01256 ast_debug(5, "Result: %s\n", buf); 01257 if (!strncasecmp(buf, "VALID", 5)) { 01258 ast_debug(3, "Passed password check: '%s'\n", buf); 01259 return 0; 01260 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01261 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01262 return 0; 01263 } else { 01264 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01265 return 1; 01266 } 01267 } 01268 } 01269 return 0; 01270 }
| static int close_mailbox | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu | |||
| ) | [static] |
Definition at line 7992 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().
07993 { 07994 int x = 0; 07995 int last_msg_idx = 0; 07996 07997 #ifndef IMAP_STORAGE 07998 int res = 0, nummsg; 07999 char fn2[PATH_MAX]; 08000 #endif 08001 08002 if (vms->lastmsg <= -1) { 08003 goto done; 08004 } 08005 08006 vms->curmsg = -1; 08007 #ifndef IMAP_STORAGE 08008 /* Get the deleted messages fixed */ 08009 if (vm_lock_path(vms->curdir)) { 08010 return ERROR_LOCK_PATH; 08011 } 08012 08013 /* update count as message may have arrived while we've got mailbox open */ 08014 last_msg_idx = last_message_index(vmu, vms->curdir); 08015 if (last_msg_idx != vms->lastmsg) { 08016 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 08017 } 08018 08019 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 08020 for (x = 0; x < last_msg_idx + 1; x++) { 08021 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 08022 /* Save this message. It's not in INBOX or hasn't been heard */ 08023 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08024 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 08025 break; 08026 } 08027 vms->curmsg++; 08028 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 08029 if (strcmp(vms->fn, fn2)) { 08030 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 08031 } 08032 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 08033 /* Move to old folder before deleting */ 08034 res = save_to_folder(vmu, vms, x, 1); 08035 if (res == ERROR_LOCK_PATH) { 08036 /* If save failed do not delete the message */ 08037 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 08038 vms->deleted[x] = 0; 08039 vms->heard[x] = 0; 08040 --x; 08041 } 08042 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 08043 /* Move to deleted folder */ 08044 res = save_to_folder(vmu, vms, x, 10); 08045 if (res == ERROR_LOCK_PATH) { 08046 /* If save failed do not delete the message */ 08047 vms->deleted[x] = 0; 08048 vms->heard[x] = 0; 08049 --x; 08050 } 08051 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 08052 /* If realtime storage enabled - we should explicitly delete this message, 08053 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08054 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08055 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08056 DELETE(vms->curdir, x, vms->fn, vmu); 08057 } 08058 } 08059 } 08060 08061 /* Delete ALL remaining messages */ 08062 nummsg = x - 1; 08063 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08064 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08065 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08066 DELETE(vms->curdir, x, vms->fn, vmu); 08067 } 08068 } 08069 ast_unlock_path(vms->curdir); 08070 #else /* defined(IMAP_STORAGE) */ 08071 ast_mutex_lock(&vms->lock); 08072 if (vms->deleted) { 08073 /* Since we now expunge after each delete, deleting in reverse order 08074 * ensures that no reordering occurs between each step. */ 08075 last_msg_idx = vms->dh_arraysize; 08076 for (x = last_msg_idx - 1; x >= 0; x--) { 08077 if (vms->deleted[x]) { 08078 ast_debug(3, "IMAP delete of %d\n", x); 08079 DELETE(vms->curdir, x, vms->fn, vmu); 08080 } 08081 } 08082 } 08083 #endif 08084 08085 done: 08086 if (vms->deleted) { 08087 ast_free(vms->deleted); 08088 vms->deleted = NULL; 08089 } 08090 if (vms->heard) { 08091 ast_free(vms->heard); 08092 vms->heard = NULL; 08093 } 08094 vms->dh_arraysize = 0; 08095 #ifdef IMAP_STORAGE 08096 ast_mutex_unlock(&vms->lock); 08097 #endif 08098 08099 return 0; 08100 }
| static char* complete_voicemail_show_users | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 11174 of file app_voicemail.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
11175 { 11176 int which = 0; 11177 int wordlen; 11178 struct ast_vm_user *vmu; 11179 const char *context = ""; 11180 11181 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11182 if (pos > 4) 11183 return NULL; 11184 if (pos == 3) 11185 return (state == 0) ? ast_strdup("for") : NULL; 11186 wordlen = strlen(word); 11187 AST_LIST_TRAVERSE(&users, vmu, list) { 11188 if (!strncasecmp(word, vmu->context, wordlen)) { 11189 if (context && strcmp(context, vmu->context) && ++which > state) 11190 return ast_strdup(vmu->context); 11191 /* ignore repeated contexts ? */ 11192 context = vmu->context; 11193 } 11194 } 11195 return NULL; 11196 }
| 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 4107 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().
04108 { 04109 int ifd; 04110 int ofd; 04111 int res; 04112 int len; 04113 char buf[4096]; 04114 04115 #ifdef HARDLINK_WHEN_POSSIBLE 04116 /* Hard link if possible; saves disk space & is faster */ 04117 if (link(infile, outfile)) { 04118 #endif 04119 if ((ifd = open(infile, O_RDONLY)) < 0) { 04120 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04121 return -1; 04122 } 04123 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04124 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04125 close(ifd); 04126 return -1; 04127 } 04128 do { 04129 len = read(ifd, buf, sizeof(buf)); 04130 if (len < 0) { 04131 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04132 close(ifd); 04133 close(ofd); 04134 unlink(outfile); 04135 } else if (len) { 04136 res = write(ofd, buf, len); 04137 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04138 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04139 close(ifd); 04140 close(ofd); 04141 unlink(outfile); 04142 } 04143 } 04144 } while (len); 04145 close(ifd); 04146 close(ofd); 04147 return 0; 04148 #ifdef HARDLINK_WHEN_POSSIBLE 04149 } else { 04150 /* Hard link succeeded */ 04151 return 0; 04152 } 04153 #endif 04154 }
| 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 5343 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().
05344 { 05345 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05346 const char *frombox = mbox(vmu, imbox); 05347 const char *userfolder; 05348 int recipmsgnum; 05349 int res = 0; 05350 05351 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05352 05353 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05354 userfolder = "Urgent"; 05355 } else { 05356 userfolder = "INBOX"; 05357 } 05358 05359 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05360 05361 if (!dir) 05362 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05363 else 05364 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05365 05366 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05367 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05368 05369 if (vm_lock_path(todir)) 05370 return ERROR_LOCK_PATH; 05371 05372 recipmsgnum = last_message_index(recip, todir) + 1; 05373 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05374 make_file(topath, sizeof(topath), todir, recipmsgnum); 05375 #ifndef ODBC_STORAGE 05376 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05377 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05378 } else { 05379 #endif 05380 /* If we are prepending a message for ODBC, then the message already 05381 * exists in the database, but we want to force copying from the 05382 * filesystem (since only the FS contains the prepend). */ 05383 copy_plain_file(frompath, topath); 05384 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05385 vm_delete(topath); 05386 #ifndef ODBC_STORAGE 05387 } 05388 #endif 05389 } else { 05390 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05391 res = -1; 05392 } 05393 ast_unlock_path(todir); 05394 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05395 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05396 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05397 flag); 05398 05399 return res; 05400 }
| 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 4165 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().
04166 { 04167 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04168 struct ast_variable *tmp,*var = NULL; 04169 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04170 ast_filecopy(frompath, topath, NULL); 04171 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04172 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04173 if (ast_check_realtime("voicemail_data")) { 04174 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04175 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04176 for (tmp = var; tmp; tmp = tmp->next) { 04177 if (!strcasecmp(tmp->name, "origmailbox")) { 04178 origmailbox = tmp->value; 04179 } else if (!strcasecmp(tmp->name, "context")) { 04180 context = tmp->value; 04181 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04182 macrocontext = tmp->value; 04183 } else if (!strcasecmp(tmp->name, "exten")) { 04184 exten = tmp->value; 04185 } else if (!strcasecmp(tmp->name, "priority")) { 04186 priority = tmp->value; 04187 } else if (!strcasecmp(tmp->name, "callerchan")) { 04188 callerchan = tmp->value; 04189 } else if (!strcasecmp(tmp->name, "callerid")) { 04190 callerid = tmp->value; 04191 } else if (!strcasecmp(tmp->name, "origdate")) { 04192 origdate = tmp->value; 04193 } else if (!strcasecmp(tmp->name, "origtime")) { 04194 origtime = tmp->value; 04195 } else if (!strcasecmp(tmp->name, "category")) { 04196 category = tmp->value; 04197 } else if (!strcasecmp(tmp->name, "duration")) { 04198 duration = tmp->value; 04199 } 04200 } 04201 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); 04202 } 04203 copy(frompath2, topath2); 04204 ast_variables_destroy(var); 04205 }
| 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 4002 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().
04003 { 04004 04005 int vmcount = 0; 04006 DIR *vmdir = NULL; 04007 struct dirent *vment = NULL; 04008 04009 if (vm_lock_path(dir)) 04010 return ERROR_LOCK_PATH; 04011 04012 if ((vmdir = opendir(dir))) { 04013 while ((vment = readdir(vmdir))) { 04014 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 04015 vmcount++; 04016 } 04017 } 04018 closedir(vmdir); 04019 } 04020 ast_unlock_path(dir); 04021 04022 return vmcount; 04023 }
| 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 1705 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().
01706 { 01707 mode_t mode = VOICEMAIL_DIR_MODE; 01708 int res; 01709 01710 make_dir(dest, len, context, ext, folder); 01711 if ((res = ast_mkdir(dest, mode))) { 01712 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01713 return -1; 01714 } 01715 return 0; 01716 }
| static int dialout | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| char * | num, | |||
| char * | outgoing_context | |||
| ) | [static] |
Definition at line 13203 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().
13204 { 13205 int cmd = 0; 13206 char destination[80] = ""; 13207 int retries = 0; 13208 13209 if (!num) { 13210 ast_verb(3, "Destination number will be entered manually\n"); 13211 while (retries < 3 && cmd != 't') { 13212 destination[1] = '\0'; 13213 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13214 if (!cmd) 13215 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13216 if (!cmd) 13217 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13218 if (!cmd) { 13219 cmd = ast_waitfordigit(chan, 6000); 13220 if (cmd) 13221 destination[0] = cmd; 13222 } 13223 if (!cmd) { 13224 retries++; 13225 } else { 13226 13227 if (cmd < 0) 13228 return 0; 13229 if (cmd == '*') { 13230 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13231 return 0; 13232 } 13233 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13234 retries++; 13235 else 13236 cmd = 't'; 13237 } 13238 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13239 } 13240 if (retries >= 3) { 13241 return 0; 13242 } 13243 13244 } else { 13245 if (option_verbose > 2) 13246 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13247 ast_copy_string(destination, num, sizeof(destination)); 13248 } 13249 13250 if (!ast_strlen_zero(destination)) { 13251 if (destination[strlen(destination) -1 ] == '*') 13252 return 0; 13253 if (option_verbose > 2) 13254 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13255 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13256 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13257 chan->priority = 0; 13258 return 9; 13259 } 13260 return 0; 13261 }
| static struct ast_vm_user* find_or_create | ( | const char * | context, | |
| const char * | box | |||
| ) | [static, read] |
Definition at line 10757 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().
10758 { 10759 struct ast_vm_user *vmu; 10760 10761 if (!ast_strlen_zero(box) && box[0] == '*') { 10762 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10763 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10764 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10765 "\n\tand will be ignored.\n", box, context); 10766 return NULL; 10767 } 10768 10769 AST_LIST_TRAVERSE(&users, vmu, list) { 10770 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10771 if (strcasecmp(vmu->context, context)) { 10772 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10773 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10774 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10775 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10776 } 10777 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10778 return NULL; 10779 } 10780 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10781 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10782 return NULL; 10783 } 10784 } 10785 10786 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10787 return NULL; 10788 10789 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10790 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10791 10792 AST_LIST_INSERT_TAIL(&users, vmu, list); 10793 10794 return vmu; 10795 }
| 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 1444 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().
01445 { 01446 /* This function could be made to generate one from a database, too */ 01447 struct ast_vm_user *vmu = NULL, *cur; 01448 AST_LIST_LOCK(&users); 01449 01450 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01451 context = "default"; 01452 01453 AST_LIST_TRAVERSE(&users, cur, list) { 01454 #ifdef IMAP_STORAGE 01455 if (cur->imapversion != imapversion) { 01456 continue; 01457 } 01458 #endif 01459 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01460 break; 01461 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01462 break; 01463 } 01464 if (cur) { 01465 /* Make a copy, so that on a reload, we have no race */ 01466 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01467 *vmu = *cur; 01468 if (!ivm) { 01469 vmu->emailbody = ast_strdup(cur->emailbody); 01470 vmu->emailsubject = ast_strdup(cur->emailsubject); 01471 } 01472 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01473 AST_LIST_NEXT(vmu, list) = NULL; 01474 } 01475 } else 01476 vmu = find_user_realtime(ivm, context, mailbox); 01477 AST_LIST_UNLOCK(&users); 01478 return vmu; 01479 }
| 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 1403 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().
01404 { 01405 struct ast_variable *var; 01406 struct ast_vm_user *retval; 01407 01408 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01409 if (ivm) { 01410 memset(retval, 0, sizeof(*retval)); 01411 } 01412 populate_defaults(retval); 01413 if (!ivm) { 01414 ast_set_flag(retval, VM_ALLOCED); 01415 } 01416 if (mailbox) { 01417 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01418 } 01419 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) { 01420 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01421 } else { 01422 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01423 } 01424 if (var) { 01425 apply_options_full(retval, var); 01426 ast_variables_destroy(var); 01427 } else { 01428 if (!ivm) 01429 free_user(retval); 01430 retval = NULL; 01431 } 01432 } 01433 return retval; 01434 }
| 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 7193 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().
07194 { 07195 #ifdef IMAP_STORAGE 07196 int todircount = 0; 07197 struct vm_state *dstvms; 07198 #endif 07199 char username[70]=""; 07200 char fn[PATH_MAX]; /* for playback of name greeting */ 07201 char ecodes[16] = "#"; 07202 int res = 0, cmd = 0; 07203 struct ast_vm_user *receiver = NULL, *vmtmp; 07204 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07205 char *stringp; 07206 const char *s; 07207 int saved_messages = 0; 07208 int valid_extensions = 0; 07209 char *dir; 07210 int curmsg; 07211 char urgent_str[7] = ""; 07212 int prompt_played = 0; 07213 #ifndef IMAP_STORAGE 07214 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07215 #endif 07216 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07217 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07218 } 07219 07220 if (vms == NULL) return -1; 07221 dir = vms->curdir; 07222 curmsg = vms->curmsg; 07223 07224 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07225 while (!res && !valid_extensions) { 07226 int use_directory = 0; 07227 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07228 int done = 0; 07229 int retries = 0; 07230 cmd = 0; 07231 while ((cmd >= 0) && !done ){ 07232 if (cmd) 07233 retries = 0; 07234 switch (cmd) { 07235 case '1': 07236 use_directory = 0; 07237 done = 1; 07238 break; 07239 case '2': 07240 use_directory = 1; 07241 done = 1; 07242 break; 07243 case '*': 07244 cmd = 't'; 07245 done = 1; 07246 break; 07247 default: 07248 /* Press 1 to enter an extension press 2 to use the directory */ 07249 cmd = ast_play_and_wait(chan, "vm-forward"); 07250 if (!cmd) { 07251 cmd = ast_waitfordigit(chan, 3000); 07252 } 07253 if (!cmd) { 07254 retries++; 07255 } 07256 if (retries > 3) { 07257 cmd = 't'; 07258 done = 1; 07259 } 07260 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07261 } 07262 } 07263 if (cmd < 0 || cmd == 't') 07264 break; 07265 } 07266 07267 if (use_directory) { 07268 /* use app_directory */ 07269 07270 char old_context[sizeof(chan->context)]; 07271 char old_exten[sizeof(chan->exten)]; 07272 int old_priority; 07273 struct ast_app* directory_app; 07274 07275 directory_app = pbx_findapp("Directory"); 07276 if (directory_app) { 07277 char vmcontext[256]; 07278 /* make backup copies */ 07279 memcpy(old_context, chan->context, sizeof(chan->context)); 07280 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07281 old_priority = chan->priority; 07282 07283 /* call the the Directory, changes the channel */ 07284 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07285 res = pbx_exec(chan, directory_app, vmcontext); 07286 07287 ast_copy_string(username, chan->exten, sizeof(username)); 07288 07289 /* restore the old context, exten, and priority */ 07290 memcpy(chan->context, old_context, sizeof(chan->context)); 07291 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07292 chan->priority = old_priority; 07293 } else { 07294 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07295 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07296 } 07297 } else { 07298 /* Ask for an extension */ 07299 ast_test_suite_event_notify("PLAYBACK", "Message: vm-extension"); 07300 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07301 prompt_played++; 07302 if (res || prompt_played > 4) 07303 break; 07304 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07305 break; 07306 } 07307 07308 /* start all over if no username */ 07309 if (ast_strlen_zero(username)) 07310 continue; 07311 stringp = username; 07312 s = strsep(&stringp, "*"); 07313 /* start optimistic */ 07314 valid_extensions = 1; 07315 while (s) { 07316 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07317 int oldmsgs; 07318 int newmsgs; 07319 int capacity; 07320 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07321 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07322 /* Shouldn't happen, but allow trying another extension if it does */ 07323 res = ast_play_and_wait(chan, "pbx-invalid"); 07324 valid_extensions = 0; 07325 break; 07326 } 07327 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07328 if ((newmsgs + oldmsgs) >= capacity) { 07329 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07330 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07331 valid_extensions = 0; 07332 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07333 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07334 free_user(vmtmp); 07335 } 07336 inprocess_count(receiver->mailbox, receiver->context, -1); 07337 break; 07338 } 07339 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07340 } else { 07341 /* XXX Optimization for the future. When we encounter a single bad extension, 07342 * bailing out on all of the extensions may not be the way to go. We should 07343 * probably just bail on that single extension, then allow the user to enter 07344 * several more. XXX 07345 */ 07346 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07347 free_user(receiver); 07348 } 07349 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07350 /* "I am sorry, that's not a valid extension. Please try again." */ 07351 res = ast_play_and_wait(chan, "pbx-invalid"); 07352 valid_extensions = 0; 07353 break; 07354 } 07355 07356 /* play name if available, else play extension number */ 07357 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07358 RETRIEVE(fn, -1, s, receiver->context); 07359 if (ast_fileexists(fn, NULL, NULL) > 0) { 07360 res = ast_stream_and_wait(chan, fn, ecodes); 07361 if (res) { 07362 DISPOSE(fn, -1); 07363 return res; 07364 } 07365 } else { 07366 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07367 } 07368 DISPOSE(fn, -1); 07369 07370 s = strsep(&stringp, "*"); 07371 } 07372 /* break from the loop of reading the extensions */ 07373 if (valid_extensions) 07374 break; 07375 } 07376 /* check if we're clear to proceed */ 07377 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07378 return res; 07379 if (is_new_message == 1) { 07380 struct leave_vm_options leave_options; 07381 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07382 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07383 07384 /* Send VoiceMail */ 07385 memset(&leave_options, 0, sizeof(leave_options)); 07386 leave_options.record_gain = record_gain; 07387 cmd = leave_voicemail(chan, mailbox, &leave_options); 07388 } else { 07389 /* Forward VoiceMail */ 07390 long duration = 0; 07391 struct vm_state vmstmp; 07392 int copy_msg_result = 0; 07393 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07394 07395 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07396 07397 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07398 if (!cmd) { 07399 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07400 #ifdef IMAP_STORAGE 07401 int attach_user_voicemail; 07402 char *myserveremail = serveremail; 07403 07404 /* get destination mailbox */ 07405 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07406 if (!dstvms) { 07407 dstvms = create_vm_state_from_user(vmtmp); 07408 } 07409 if (dstvms) { 07410 init_mailstream(dstvms, 0); 07411 if (!dstvms->mailstream) { 07412 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07413 } else { 07414 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07415 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07416 } 07417 } else { 07418 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07419 } 07420 if (!ast_strlen_zero(vmtmp->serveremail)) 07421 myserveremail = vmtmp->serveremail; 07422 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07423 /* NULL category for IMAP storage */ 07424 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07425 dstvms->curbox, 07426 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07427 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07428 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07429 NULL, urgent_str); 07430 #else 07431 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07432 #endif 07433 saved_messages++; 07434 AST_LIST_REMOVE_CURRENT(list); 07435 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07436 free_user(vmtmp); 07437 if (res) 07438 break; 07439 } 07440 AST_LIST_TRAVERSE_SAFE_END; 07441 if (saved_messages > 0 && !copy_msg_result) { 07442 /* give confirmation that the message was saved */ 07443 /* commented out since we can't forward batches yet 07444 if (saved_messages == 1) 07445 res = ast_play_and_wait(chan, "vm-message"); 07446 else 07447 res = ast_play_and_wait(chan, "vm-messages"); 07448 if (!res) 07449 res = ast_play_and_wait(chan, "vm-saved"); */ 07450 #ifdef IMAP_STORAGE 07451 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07452 if (ast_strlen_zero(vmstmp.introfn)) 07453 #endif 07454 res = ast_play_and_wait(chan, "vm-msgsaved"); 07455 } 07456 #ifndef IMAP_STORAGE 07457 else { 07458 /* with IMAP, mailbox full warning played by imap_check_limits */ 07459 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07460 } 07461 /* Restore original message without prepended message if backup exists */ 07462 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07463 strcpy(textfile, msgfile); 07464 strcpy(backup, msgfile); 07465 strcpy(backup_textfile, msgfile); 07466 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07467 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07468 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07469 if (ast_fileexists(backup, NULL, NULL) > 0) { 07470 ast_filerename(backup, msgfile, NULL); 07471 rename(backup_textfile, textfile); 07472 } 07473 #endif 07474 } 07475 DISPOSE(dir, curmsg); 07476 #ifndef IMAP_STORAGE 07477 if (cmd) { /* assuming hangup, cleanup backup file */ 07478 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07479 strcpy(textfile, msgfile); 07480 strcpy(backup_textfile, msgfile); 07481 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07482 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07483 rename(backup_textfile, textfile); 07484 } 07485 #endif 07486 } 07487 07488 /* If anything failed above, we still have this list to free */ 07489 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07490 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07491 free_user(vmtmp); 07492 } 07493 return res ? res : cmd; 07494 }
| static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1760 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().
01761 { 01762 if (ast_test_flag(vmu, VM_ALLOCED)) { 01763 01764 ast_free(vmu->emailbody); 01765 vmu->emailbody = NULL; 01766 01767 ast_free(vmu->emailsubject); 01768 vmu->emailsubject = NULL; 01769 01770 ast_free(vmu); 01771 } 01772 }
| static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11786 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().
11787 { 11788 struct ast_vm_user *current; 11789 AST_LIST_LOCK(&users); 11790 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11791 ast_set_flag(current, VM_ALLOCED); 11792 free_user(current); 11793 } 11794 AST_LIST_UNLOCK(&users); 11795 }
| static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11798 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().
11799 { 11800 struct vm_zone *zcur; 11801 AST_LIST_LOCK(&zones); 11802 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11803 free_zone(zcur); 11804 AST_LIST_UNLOCK(&zones); 11805 }
| static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5111 of file app_voicemail.c.
References ast_free.
Referenced by free_vm_zones().
05112 { 05113 ast_free(z); 05114 }
| 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 5067 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail().
05068 { 05069 struct ast_tm tm; 05070 struct timeval t = ast_tvnow(); 05071 05072 ast_localtime(&t, &tm, "UTC"); 05073 05074 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05075 }
| 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 6802 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().
06803 { 06804 int x; 06805 int d; 06806 char fn[PATH_MAX]; 06807 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06808 if (d) 06809 return d; 06810 for (x = start; x < 5; x++) { /* For all folders */ 06811 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06812 return d; 06813 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06814 if (d) 06815 return d; 06816 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06817 06818 /* The inbox folder can have its name changed under certain conditions 06819 * so this checks if the sound file exists for the inbox folder name and 06820 * if it doesn't, plays the default name instead. */ 06821 if (x == 0) { 06822 if (ast_fileexists(fn, NULL, NULL)) { 06823 d = vm_play_folder_name(chan, fn); 06824 } else { 06825 ast_verb(1, "failed to find %s\n", fn); 06826 d = vm_play_folder_name(chan, "vm-INBOX"); 06827 } 06828 } else { 06829 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06830 d = vm_play_folder_name(chan, fn); 06831 } 06832 06833 if (d) 06834 return d; 06835 d = ast_waitfordigit(chan, 500); 06836 if (d) 06837 return d; 06838 } 06839 06840 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06841 if (d) 06842 return d; 06843 d = ast_waitfordigit(chan, 4000); 06844 return d; 06845 }
| 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 6859 of file app_voicemail.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
Referenced by vm_execmain().
06860 { 06861 int res = 0; 06862 int loops = 0; 06863 06864 res = ast_play_and_wait(chan, fn); /* Folder name */ 06865 while (((res < '0') || (res > '9')) && 06866 (res != '#') && (res >= 0) && 06867 loops < 4) { 06868 res = get_folder(chan, 0); 06869 loops++; 06870 } 06871 if (loops == 4) { /* give up */ 06872 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06873 return '#'; 06874 } 06875 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06876 return res; 06877 }
| static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1747 of file app_voicemail.c.
References ARRAY_LEN, and mailbox_folders.
Referenced by vm_execmain().
01748 { 01749 size_t i; 01750 01751 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01752 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01753 return i; 01754 } 01755 } 01756 01757 return -1; 01758 }
| static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11556 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().
11557 { 11558 unsigned int len; 11559 struct mwi_sub *mwi_sub; 11560 struct mwi_sub_task *p = datap; 11561 11562 len = sizeof(*mwi_sub); 11563 if (!ast_strlen_zero(p->mailbox)) 11564 len += strlen(p->mailbox); 11565 11566 if (!ast_strlen_zero(p->context)) 11567 len += strlen(p->context) + 1; /* Allow for seperator */ 11568 11569 if (!(mwi_sub = ast_calloc(1, len))) 11570 return -1; 11571 11572 mwi_sub->uniqueid = p->uniqueid; 11573 if (!ast_strlen_zero(p->mailbox)) 11574 strcpy(mwi_sub->mailbox, p->mailbox); 11575 11576 if (!ast_strlen_zero(p->context)) { 11577 strcat(mwi_sub->mailbox, "@"); 11578 strcat(mwi_sub->mailbox, p->context); 11579 } 11580 11581 AST_RWLIST_WRLOCK(&mwi_subs); 11582 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11583 AST_RWLIST_UNLOCK(&mwi_subs); 11584 ast_free((void *) p->mailbox); 11585 ast_free((void *) p->context); 11586 ast_free(p); 11587 poll_subscribed_mailbox(mwi_sub); 11588 return 0; 11589 }
| static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11534 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().
11535 { 11536 struct mwi_sub *mwi_sub; 11537 uint32_t *uniqueid = datap; 11538 11539 AST_RWLIST_WRLOCK(&mwi_subs); 11540 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11541 if (mwi_sub->uniqueid == *uniqueid) { 11542 AST_LIST_REMOVE_CURRENT(entry); 11543 break; 11544 } 11545 } 11546 AST_RWLIST_TRAVERSE_SAFE_END 11547 AST_RWLIST_UNLOCK(&mwi_subs); 11548 11549 if (mwi_sub) 11550 mwi_sub_destroy(mwi_sub); 11551 11552 ast_free(uniqueid); 11553 return 0; 11554 }
| 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 11311 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.
11312 { 11313 switch (cmd) { 11314 case CLI_INIT: 11315 e->command = "voicemail reload"; 11316 e->usage = 11317 "Usage: voicemail reload\n" 11318 " Reload voicemail configuration\n"; 11319 return NULL; 11320 case CLI_GENERATE: 11321 return NULL; 11322 } 11323 11324 if (a->argc != 2) 11325 return CLI_SHOWUSAGE; 11326 11327 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11328 load_config(1); 11329 11330 return CLI_SUCCESS; 11331 }
| 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 11199 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.
11200 { 11201 struct ast_vm_user *vmu; 11202 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11203 const char *context = NULL; 11204 int users_counter = 0; 11205 11206 switch (cmd) { 11207 case CLI_INIT: 11208 e->command = "voicemail show users"; 11209 e->usage = 11210 "Usage: voicemail show users [for <context>]\n" 11211 " Lists all mailboxes currently set up\n"; 11212 return NULL; 11213 case CLI_GENERATE: 11214 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11215 } 11216 11217 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11218 return CLI_SHOWUSAGE; 11219 if (a->argc == 5) { 11220 if (strcmp(a->argv[3],"for")) 11221 return CLI_SHOWUSAGE; 11222 context = a->argv[4]; 11223 } 11224 11225 if (ast_check_realtime("voicemail")) { 11226 if (!context) { 11227 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11228 return CLI_SHOWUSAGE; 11229 } 11230 return show_users_realtime(a->fd, context); 11231 } 11232 11233 AST_LIST_LOCK(&users); 11234 if (AST_LIST_EMPTY(&users)) { 11235 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11236 AST_LIST_UNLOCK(&users); 11237 return CLI_FAILURE; 11238 } 11239 if (!context) { 11240 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11241 } else { 11242 int count = 0; 11243 AST_LIST_TRAVERSE(&users, vmu, list) { 11244 if (!strcmp(context, vmu->context)) { 11245 count++; 11246 break; 11247 } 11248 } 11249 if (count) { 11250 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11251 } else { 11252 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11253 AST_LIST_UNLOCK(&users); 11254 return CLI_FAILURE; 11255 } 11256 } 11257 AST_LIST_TRAVERSE(&users, vmu, list) { 11258 int newmsgs = 0, oldmsgs = 0; 11259 char count[12], tmp[256] = ""; 11260 11261 if (!context || !strcmp(context, vmu->context)) { 11262 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11263 inboxcount(tmp, &newmsgs, &oldmsgs); 11264 snprintf(count, sizeof(count), "%d", newmsgs); 11265 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11266 users_counter++; 11267 } 11268 } 11269 AST_LIST_UNLOCK(&users); 11270 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11271 return CLI_SUCCESS; 11272 }
| 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 11275 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.
11276 { 11277 struct vm_zone *zone; 11278 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11279 char *res = CLI_SUCCESS; 11280 11281 switch (cmd) { 11282 case CLI_INIT: 11283 e->command = "voicemail show zones"; 11284 e->usage = 11285 "Usage: voicemail show zones\n" 11286 " Lists zone message formats\n"; 11287 return NULL; 11288 case CLI_GENERATE: 11289 return NULL; 11290 } 11291 11292 if (a->argc != 3) 11293 return CLI_SHOWUSAGE; 11294 11295 AST_LIST_LOCK(&zones); 11296 if (!AST_LIST_EMPTY(&zones)) { 11297 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11298 AST_LIST_TRAVERSE(&zones, zone, list) { 11299 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11300 } 11301 } else { 11302 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11303 res = CLI_FAILURE; 11304 } 11305 AST_LIST_UNLOCK(&zones); 11306 11307 return res; 11308 }
| 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 5455 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), and ast_strlen_zero().
Referenced by load_module(), and vm_execmain().
05456 { 05457 char tmp[256], *tmp2 = tmp, *box, *context; 05458 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05459 if (ast_strlen_zero(folder)) { 05460 folder = "INBOX"; 05461 } 05462 while ((box = strsep(&tmp2, ",&"))) { 05463 if ((context = strchr(box, '@'))) 05464 *context++ = '\0'; 05465 else 05466 context = "default"; 05467 if (__has_voicemail(context, box, folder, 1)) 05468 return 1; 05469 /* If we are checking INBOX, we should check Urgent as well */ 05470 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05471 return 1; 05472 } 05473 } 05474 return 0; 05475 }
| static int inboxcount | ( | const char * | mailbox, | |
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) | [static] |
Definition at line 5537 of file app_voicemail.c.
References inboxcount2().
Referenced by forward_message(), handle_voicemail_show_users(), leave_voicemail(), load_module(), and manager_list_voicemail_users().
05538 { 05539 int urgentmsgs = 0; 05540 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05541 if (newmsgs) { 05542 *newmsgs += urgentmsgs; 05543 } 05544 return res; 05545 }
| static int inboxcount2 | ( | const char * | mailbox, | |
| int * | urgentmsgs, | |||
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) | [static] |
Definition at line 5478 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().
05479 { 05480 char tmp[256]; 05481 char *context; 05482 05483 /* If no mailbox, return immediately */ 05484 if (ast_strlen_zero(mailbox)) 05485 return 0; 05486 05487 if (newmsgs) 05488 *newmsgs = 0; 05489 if (oldmsgs) 05490 *oldmsgs = 0; 05491 if (urgentmsgs) 05492 *urgentmsgs = 0; 05493 05494 if (strchr(mailbox, ',')) { 05495 int tmpnew, tmpold, tmpurgent; 05496 char *mb, *cur; 05497 05498 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05499 mb = tmp; 05500 while ((cur = strsep(&mb, ", "))) { 05501 if (!ast_strlen_zero(cur)) { 05502 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05503 return -1; 05504 else { 05505 if (newmsgs) 05506 *newmsgs += tmpnew; 05507 if (oldmsgs) 05508 *oldmsgs += tmpold; 05509 if (urgentmsgs) 05510 *urgentmsgs += tmpurgent; 05511 } 05512 } 05513 } 05514 return 0; 05515 } 05516 05517 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05518 05519 if ((context = strchr(tmp, '@'))) 05520 *context++ = '\0'; 05521 else 05522 context = "default"; 05523 05524 if (newmsgs) 05525 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05526 if (oldmsgs) 05527 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05528 if (urgentmsgs) 05529 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05530 05531 return 0; 05532 }
| static int inbuf | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4237 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().
04238 { 04239 int l; 04240 04241 if (bio->ateof) 04242 return 0; 04243 04244 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04245 if (ferror(fi)) 04246 return -1; 04247 04248 bio->ateof = 1; 04249 return 0; 04250 } 04251 04252 bio->iolen = l; 04253 bio->iocp = 0; 04254 04255 return 1; 04256 }
| static int inchar | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
utility used by base_encode()
Definition at line 4261 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 942 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 951 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().
00952 { 00953 struct inprocess *i, *arg = ast_alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 00954 arg->context = arg->mailbox + strlen(mailbox) + 1; 00955 strcpy(arg->mailbox, mailbox); /* SAFE */ 00956 strcpy(arg->context, context); /* SAFE */ 00957 ao2_lock(inprocess_container); 00958 if ((i = ao2_find(inprocess_container, arg, 0))) { 00959 int ret = ast_atomic_fetchadd_int(&i->count, delta); 00960 ao2_unlock(inprocess_container); 00961 ao2_ref(i, -1); 00962 return ret; 00963 } 00964 if (delta < 0) { 00965 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 00966 } 00967 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 00968 ao2_unlock(inprocess_container); 00969 return 0; 00970 } 00971 i->context = i->mailbox + strlen(mailbox) + 1; 00972 strcpy(i->mailbox, mailbox); /* SAFE */ 00973 strcpy(i->context, context); /* SAFE */ 00974 i->count = delta; 00975 ao2_link(inprocess_container, i); 00976 ao2_unlock(inprocess_container); 00977 ao2_ref(i, -1); 00978 return 0; 00979 }
| static int inprocess_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 936 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 5077 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().
05078 { 05079 int res; 05080 char fn[PATH_MAX]; 05081 char dest[PATH_MAX]; 05082 05083 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05084 05085 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05086 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05087 return -1; 05088 } 05089 05090 RETRIEVE(fn, -1, ext, context); 05091 if (ast_fileexists(fn, NULL, NULL) > 0) { 05092 res = ast_stream_and_wait(chan, fn, ecodes); 05093 if (res) { 05094 DISPOSE(fn, -1); 05095 return res; 05096 } 05097 } else { 05098 /* Dispose just in case */ 05099 DISPOSE(fn, -1); 05100 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05101 if (res) 05102 return res; 05103 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 05104 if (res) 05105 return res; 05106 } 05107 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05108 return res; 05109 }
| 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 1378 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by actual_load_config().
01379 { 01380 int i; 01381 char *local_key = ast_strdupa(key); 01382 01383 for (i = 0; i < strlen(key); ++i) { 01384 if (!strchr(VALID_DTMF, *local_key)) { 01385 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01386 return 0; 01387 } 01388 local_key++; 01389 } 01390 return 1; 01391 }
| 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 4056 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().
04057 { 04058 int x; 04059 unsigned char map[MAXMSGLIMIT] = ""; 04060 DIR *msgdir; 04061 struct dirent *msgdirent; 04062 int msgdirint; 04063 char extension[4]; 04064 int stopcount = 0; 04065 04066 /* Reading the entire directory into a file map scales better than 04067 * doing a stat repeatedly on a predicted sequence. I suspect this 04068 * is partially due to stat(2) internally doing a readdir(2) itself to 04069 * find each file. */ 04070 if (!(msgdir = opendir(dir))) { 04071 return -1; 04072 } 04073 04074 while ((msgdirent = readdir(msgdir))) { 04075 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04076 map[msgdirint] = 1; 04077 stopcount++; 04078 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04079 } 04080 } 04081 closedir(msgdir); 04082 04083 for (x = 0; x < vmu->maxmsg; x++) { 04084 if (map[x] == 1) { 04085 stopcount--; 04086 } else if (map[x] == 0 && !stopcount) { 04087 break; 04088 } 04089 } 04090 04091 return x - 1; 04092 }
| 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 5613 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().
05614 { 05615 #ifdef IMAP_STORAGE 05616 int newmsgs, oldmsgs; 05617 #else 05618 char urgdir[PATH_MAX]; 05619 #endif 05620 char txtfile[PATH_MAX]; 05621 char tmptxtfile[PATH_MAX]; 05622 struct vm_state *vms = NULL; 05623 char callerid[256]; 05624 FILE *txt; 05625 char date[256]; 05626 int txtdes; 05627 int res = 0; 05628 int msgnum; 05629 int duration = 0; 05630 int sound_duration = 0; 05631 int ausemacro = 0; 05632 int ousemacro = 0; 05633 int ouseexten = 0; 05634 char tmpdur[16]; 05635 char priority[16]; 05636 char origtime[16]; 05637 char dir[PATH_MAX]; 05638 char tmpdir[PATH_MAX]; 05639 char fn[PATH_MAX]; 05640 char prefile[PATH_MAX] = ""; 05641 char tempfile[PATH_MAX] = ""; 05642 char ext_context[256] = ""; 05643 char fmt[80]; 05644 char *context; 05645 char ecodes[17] = "#"; 05646 struct ast_str *tmp = ast_str_create(16); 05647 char *tmpptr; 05648 struct ast_vm_user *vmu; 05649 struct ast_vm_user svm; 05650 const char *category = NULL; 05651 const char *code; 05652 const char *alldtmf = "0123456789ABCD*#"; 05653 char flag[80]; 05654 05655 if (!tmp) { 05656 return -1; 05657 } 05658 05659 ast_str_set(&tmp, 0, "%s", ext); 05660 ext = ast_str_buffer(tmp); 05661 if ((context = strchr(ext, '@'))) { 05662 *context++ = '\0'; 05663 tmpptr = strchr(context, '&'); 05664 } else { 05665 tmpptr = strchr(ext, '&'); 05666 } 05667 05668 if (tmpptr) 05669 *tmpptr++ = '\0'; 05670 05671 ast_channel_lock(chan); 05672 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05673 category = ast_strdupa(category); 05674 } 05675 ast_channel_unlock(chan); 05676 05677 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05678 ast_copy_string(flag, "Urgent", sizeof(flag)); 05679 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05680 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05681 } else { 05682 flag[0] = '\0'; 05683 } 05684 05685 ast_debug(3, "Before find_user\n"); 05686 if (!(vmu = find_user(&svm, context, ext))) { 05687 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05688 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05689 ast_free(tmp); 05690 return res; 05691 } 05692 /* Setup pre-file if appropriate */ 05693 if (strcmp(vmu->context, "default")) 05694 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05695 else 05696 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05697 05698 /* Set the path to the prefile. Will be one of 05699 VM_SPOOL_DIRcontext/ext/busy 05700 VM_SPOOL_DIRcontext/ext/unavail 05701 Depending on the flag set in options. 05702 */ 05703 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05704 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05705 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05706 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05707 } 05708 /* Set the path to the tmpfile as 05709 VM_SPOOL_DIR/context/ext/temp 05710 and attempt to create the folder structure. 05711 */ 05712 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05713 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05714 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05715 ast_free(tmp); 05716 return -1; 05717 } 05718 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05719 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05720 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05721 05722 DISPOSE(tempfile, -1); 05723 /* It's easier just to try to make it than to check for its existence */ 05724 #ifndef IMAP_STORAGE 05725 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05726 #else 05727 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05728 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05729 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05730 } 05731 #endif 05732 05733 /* Check current or macro-calling context for special extensions */ 05734 if (ast_test_flag(vmu, VM_OPERATOR)) { 05735 if (!ast_strlen_zero(vmu->exit)) { 05736 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05737 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05738 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05739 ouseexten = 1; 05740 } 05741 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05742 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05743 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05744 ouseexten = 1; 05745 } else if (!ast_strlen_zero(chan->macrocontext) 05746 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05747 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05748 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05749 ousemacro = 1; 05750 } 05751 } 05752 05753 if (!ast_strlen_zero(vmu->exit)) { 05754 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05755 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05756 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05757 } 05758 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05759 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05760 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05761 } else if (!ast_strlen_zero(chan->macrocontext) 05762 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05763 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05764 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05765 ausemacro = 1; 05766 } 05767 05768 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05769 for (code = alldtmf; *code; code++) { 05770 char e[2] = ""; 05771 e[0] = *code; 05772 if (strchr(ecodes, e[0]) == NULL 05773 && ast_canmatch_extension(chan, 05774 (!ast_strlen_zero(options->exitcontext) ? options->exitcontext : chan->context), 05775 e, 1, S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05776 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05777 } 05778 } 05779 } 05780 05781 /* Play the beginning intro if desired */ 05782 if (!ast_strlen_zero(prefile)) { 05783 #ifdef ODBC_STORAGE 05784 int success = 05785 #endif 05786 RETRIEVE(prefile, -1, ext, context); 05787 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05788 if (ast_streamfile(chan, prefile, chan->language) > -1) 05789 res = ast_waitstream(chan, ecodes); 05790 #ifdef ODBC_STORAGE 05791 if (success == -1) { 05792 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05793 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05794 store_file(prefile, vmu->mailbox, vmu->context, -1); 05795 } 05796 #endif 05797 } else { 05798 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05799 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05800 } 05801 DISPOSE(prefile, -1); 05802 if (res < 0) { 05803 ast_debug(1, "Hang up during prefile playback\n"); 05804 free_user(vmu); 05805 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05806 ast_free(tmp); 05807 return -1; 05808 } 05809 } 05810 if (res == '#') { 05811 /* On a '#' we skip the instructions */ 05812 ast_set_flag(options, OPT_SILENT); 05813 res = 0; 05814 } 05815 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05816 if (vmu->maxmsg == 0) { 05817 if (option_debug > 2) 05818 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05819 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05820 goto leave_vm_out; 05821 } 05822 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05823 res = ast_stream_and_wait(chan, INTRO, ecodes); 05824 if (res == '#') { 05825 ast_set_flag(options, OPT_SILENT); 05826 res = 0; 05827 } 05828 } 05829 if (res > 0) 05830 ast_stopstream(chan); 05831 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05832 other than the operator -- an automated attendant or mailbox login for example */ 05833 if (res == '*') { 05834 chan->exten[0] = 'a'; 05835 chan->exten[1] = '\0'; 05836 if (!ast_strlen_zero(vmu->exit)) { 05837 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05838 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05839 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05840 } 05841 chan->priority = 0; 05842 free_user(vmu); 05843 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05844 ast_free(tmp); 05845 return 0; 05846 } 05847 05848 /* Check for a '0' here */ 05849 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05850 transfer: 05851 if (ouseexten || ousemacro) { 05852 chan->exten[0] = 'o'; 05853 chan->exten[1] = '\0'; 05854 if (!ast_strlen_zero(vmu->exit)) { 05855 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05856 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05857 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05858 } 05859 ast_play_and_wait(chan, "transfer"); 05860 chan->priority = 0; 05861 free_user(vmu); 05862 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05863 } 05864 ast_free(tmp); 05865 return OPERATOR_EXIT; 05866 } 05867 05868 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05869 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05870 if (!ast_strlen_zero(options->exitcontext)) { 05871 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05872 } 05873 free_user(vmu); 05874 ast_free(tmp); 05875 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05876 return res; 05877 } 05878 05879 if (res < 0) { 05880 free_user(vmu); 05881 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05882 ast_free(tmp); 05883 return -1; 05884 } 05885 /* The meat of recording the message... All the announcements and beeps have been played*/ 05886 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05887 if (!ast_strlen_zero(fmt)) { 05888 msgnum = 0; 05889 05890 #ifdef IMAP_STORAGE 05891 /* Is ext a mailbox? */ 05892 /* must open stream for this user to get info! */ 05893 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05894 if (res < 0) { 05895 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05896 ast_free(tmp); 05897 return -1; 05898 } 05899 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05900 /* It is possible under certain circumstances that inboxcount did not 05901 * create a vm_state when it was needed. This is a catchall which will 05902 * rarely be used. 05903 */ 05904 if (!(vms = create_vm_state_from_user(vmu))) { 05905 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05906 ast_free(tmp); 05907 return -1; 05908 } 05909 } 05910 vms->newmessages++; 05911 05912 /* here is a big difference! We add one to it later */ 05913 msgnum = newmsgs + oldmsgs; 05914 ast_debug(3, "Messagecount set to %d\n", msgnum); 05915 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05916 /* set variable for compatibility */ 05917 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05918 05919 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05920 goto leave_vm_out; 05921 } 05922 #else 05923 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05924 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05925 if (!res) 05926 res = ast_waitstream(chan, ""); 05927 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05928 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05929 inprocess_count(vmu->mailbox, vmu->context, -1); 05930 goto leave_vm_out; 05931 } 05932 05933 #endif 05934 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05935 txtdes = mkstemp(tmptxtfile); 05936 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05937 if (txtdes < 0) { 05938 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05939 if (!res) 05940 res = ast_waitstream(chan, ""); 05941 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05942 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05943 inprocess_count(vmu->mailbox, vmu->context, -1); 05944 goto leave_vm_out; 05945 } 05946 05947 /* Now play the beep once we have the message number for our next message. */ 05948 if (res >= 0) { 05949 /* Unless we're *really* silent, try to send the beep */ 05950 res = ast_stream_and_wait(chan, "beep", ""); 05951 } 05952 05953 /* Store information in real-time storage */ 05954 if (ast_check_realtime("voicemail_data")) { 05955 snprintf(priority, sizeof(priority), "%d", chan->priority); 05956 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05957 get_date(date, sizeof(date)); 05958 ast_callerid_merge(callerid, sizeof(callerid), 05959 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05960 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05961 "Unknown"); 05962 ast_store_realtime("voicemail_data", 05963 "origmailbox", ext, 05964 "context", chan->context, 05965 "macrocontext", chan->macrocontext, 05966 "exten", chan->exten, 05967 "priority", priority, 05968 "callerchan", chan->name, 05969 "callerid", callerid, 05970 "origdate", date, 05971 "origtime", origtime, 05972 "category", S_OR(category, ""), 05973 "filename", tmptxtfile, 05974 SENTINEL); 05975 } 05976 05977 /* Store information */ 05978 txt = fdopen(txtdes, "w+"); 05979 if (txt) { 05980 get_date(date, sizeof(date)); 05981 ast_callerid_merge(callerid, sizeof(callerid), 05982 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05983 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05984 "Unknown"); 05985 fprintf(txt, 05986 ";\n" 05987 "; Message Information file\n" 05988 ";\n" 05989 "[message]\n" 05990 "origmailbox=%s\n" 05991 "context=%s\n" 05992 "macrocontext=%s\n" 05993 "exten=%s\n" 05994 "rdnis=%s\n" 05995 "priority=%d\n" 05996 "callerchan=%s\n" 05997 "callerid=%s\n" 05998 "origdate=%s\n" 05999 "origtime=%ld\n" 06000 "category=%s\n", 06001 ext, 06002 chan->context, 06003 chan->macrocontext, 06004 chan->exten, 06005 S_COR(chan->redirecting.from.number.valid, 06006 chan->redirecting.from.number.str, "unknown"), 06007 chan->priority, 06008 chan->name, 06009 callerid, 06010 date, (long) time(NULL), 06011 category ? category : ""); 06012 } else { 06013 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 06014 inprocess_count(vmu->mailbox, vmu->context, -1); 06015 if (ast_check_realtime("voicemail_data")) { 06016 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06017 } 06018 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 06019 goto leave_vm_out; 06020 } 06021 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 06022 06023 if (txt) { 06024 fprintf(txt, "flag=%s\n", flag); 06025 if (sound_duration < vmu->minsecs) { 06026 fclose(txt); 06027 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 06028 ast_filedelete(tmptxtfile, NULL); 06029 unlink(tmptxtfile); 06030 if (ast_check_realtime("voicemail_data")) { 06031 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06032 } 06033 inprocess_count(vmu->mailbox, vmu->context, -1); 06034 } else { 06035 fprintf(txt, "duration=%d\n", duration); 06036 fclose(txt); 06037 if (vm_lock_path(dir)) { 06038 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 06039 /* Delete files */ 06040 ast_filedelete(tmptxtfile, NULL); 06041 unlink(tmptxtfile); 06042 inprocess_count(vmu->mailbox, vmu->context, -1); 06043 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06044 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06045 unlink(tmptxtfile); 06046 ast_unlock_path(dir); 06047 inprocess_count(vmu->mailbox, vmu->context, -1); 06048 if (ast_check_realtime("voicemail_data")) { 06049 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06050 } 06051 } else { 06052 #ifndef IMAP_STORAGE 06053 msgnum = last_message_index(vmu, dir) + 1; 06054 #endif 06055 make_file(fn, sizeof(fn), dir, msgnum); 06056 06057 /* assign a variable with the name of the voicemail file */ 06058 #ifndef IMAP_STORAGE 06059 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06060 #else 06061 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06062 #endif 06063 06064 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06065 ast_filerename(tmptxtfile, fn, NULL); 06066 rename(tmptxtfile, txtfile); 06067 inprocess_count(vmu->mailbox, vmu->context, -1); 06068 06069 /* Properly set permissions on voicemail text descriptor file. 06070 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06071 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06072 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06073 06074 ast_unlock_path(dir); 06075 if (ast_check_realtime("voicemail_data")) { 06076 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06077 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06078 } 06079 /* We must store the file first, before copying the message, because 06080 * ODBC storage does the entire copy with SQL. 06081 */ 06082 if (ast_fileexists(fn, NULL, NULL) > 0) { 06083 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06084 } 06085 06086 /* Are there to be more recipients of this message? */ 06087 while (tmpptr) { 06088 struct ast_vm_user recipu, *recip; 06089 char *exten, *cntx; 06090 06091 exten = strsep(&tmpptr, "&"); 06092 cntx = strchr(exten, '@'); 06093 if (cntx) { 06094 *cntx = '\0'; 06095 cntx++; 06096 } 06097 if ((recip = find_user(&recipu, cntx, exten))) { 06098 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06099 free_user(recip); 06100 } 06101 } 06102 #ifndef IMAP_STORAGE 06103 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06104 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06105 char sfn[PATH_MAX]; 06106 char dfn[PATH_MAX]; 06107 int x; 06108 /* It's easier just to try to make it than to check for its existence */ 06109 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06110 x = last_message_index(vmu, urgdir) + 1; 06111 make_file(sfn, sizeof(sfn), dir, msgnum); 06112 make_file(dfn, sizeof(dfn), urgdir, x); 06113 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06114 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06115 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06116 ast_copy_string(fn, dfn, sizeof(fn)); 06117 msgnum = x; 06118 } 06119 #endif 06120 /* Notification needs to happen after the copy, though. */ 06121 if (ast_fileexists(fn, NULL, NULL)) { 06122 #ifdef IMAP_STORAGE 06123 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06124 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06125 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06126 flag); 06127 #else 06128 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06129 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06130 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06131 flag); 06132 #endif 06133 } 06134 06135 /* Disposal needs to happen after the optional move and copy */ 06136 if (ast_fileexists(fn, NULL, NULL)) { 06137 DISPOSE(dir, msgnum); 06138 } 06139 } 06140 } 06141 } else { 06142 inprocess_count(vmu->mailbox, vmu->context, -1); 06143 } 06144 if (res == '0') { 06145 goto transfer; 06146 } else if (res > 0 && res != 't') 06147 res = 0; 06148 06149 if (sound_duration < vmu->minsecs) 06150 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06151 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06152 else 06153 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06154 } else 06155 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06156 leave_vm_out: 06157 free_user(vmu); 06158 06159 #ifdef IMAP_STORAGE 06160 /* expunge message - use UID Expunge if supported on IMAP server*/ 06161 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06162 if (expungeonhangup == 1) { 06163 ast_mutex_lock(&vms->lock); 06164 #ifdef HAVE_IMAP_TK2006 06165 if (LEVELUIDPLUS (vms->mailstream)) { 06166 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06167 } else 06168 #endif 06169 mail_expunge(vms->mailstream); 06170 ast_mutex_unlock(&vms->lock); 06171 } 06172 #endif 06173 06174 ast_free(tmp); 06175 return res; 06176 }
| static int load_config | ( | int | reload | ) | [static] |
Definition at line 11854 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().
11855 { 11856 struct ast_config *cfg, *ucfg; 11857 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11858 int res; 11859 11860 ast_unload_realtime("voicemail"); 11861 ast_unload_realtime("voicemail_data"); 11862 11863 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11864 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11865 return 0; 11866 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11867 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11868 ucfg = NULL; 11869 } 11870 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11871 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11872 ast_config_destroy(ucfg); 11873 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11874 return 0; 11875 } 11876 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11877 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11878 return 0; 11879 } else { 11880 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11881 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11882 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11883 ucfg = NULL; 11884 } 11885 } 11886 11887 res = actual_load_config(reload, cfg, ucfg); 11888 11889 ast_config_destroy(cfg); 11890 ast_config_destroy(ucfg); 11891 11892 return res; 11893 }
| static int load_module | ( | void | ) | [static] |
Definition at line 13155 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().
13156 { 13157 int res; 13158 my_umask = umask(0); 13159 umask(my_umask); 13160 13161 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13162 return AST_MODULE_LOAD_DECLINE; 13163 } 13164 13165 /* compute the location of the voicemail spool directory */ 13166 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13167 13168 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13169 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13170 } 13171 13172 if ((res = load_config(0))) 13173 return res; 13174 13175 res = ast_register_application_xml(app, vm_exec); 13176 res |= ast_register_application_xml(app2, vm_execmain); 13177 res |= ast_register_application_xml(app3, vm_box_exists); 13178 res |= ast_register_application_xml(app4, vmauthenticate); 13179 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13180 res |= ast_custom_function_register(&mailbox_exists_acf); 13181 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13182 #ifdef TEST_FRAMEWORK 13183 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13184 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13185 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13186 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13187 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13188 #endif 13189 13190 if (res) 13191 return res; 13192 13193 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13194 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13195 13196 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13197 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13198 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13199 13200 return res; 13201 }
| 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 1659 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().
01660 { 01661 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01662 }
| 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 4554 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().
04555 { 04556 char date[256]; 04557 char host[MAXHOSTNAMELEN] = ""; 04558 char who[256]; 04559 char bound[256]; 04560 char dur[256]; 04561 struct ast_tm tm; 04562 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04563 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04564 char *greeting_attachment; 04565 char filename[256]; 04566 04567 if (!str1 || !str2) { 04568 ast_free(str1); 04569 ast_free(str2); 04570 return; 04571 } 04572 04573 if (cidnum) { 04574 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04575 } 04576 if (cidname) { 04577 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04578 } 04579 gethostname(host, sizeof(host) - 1); 04580 04581 if (strchr(srcemail, '@')) { 04582 ast_copy_string(who, srcemail, sizeof(who)); 04583 } else { 04584 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04585 } 04586 04587 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04588 if (greeting_attachment) { 04589 *greeting_attachment++ = '\0'; 04590 } 04591 04592 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04593 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04594 fprintf(p, "Date: %s" ENDL, date); 04595 04596 /* Set date format for voicemail mail */ 04597 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04598 04599 if (!ast_strlen_zero(fromstring)) { 04600 struct ast_channel *ast; 04601 if ((ast = ast_dummy_channel_alloc())) { 04602 char *ptr; 04603 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04604 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04605 04606 if (check_mime(ast_str_buffer(str1))) { 04607 int first_line = 1; 04608 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04609 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04610 *ptr = '\0'; 04611 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04612 first_line = 0; 04613 /* Substring is smaller, so this will never grow */ 04614 ast_str_set(&str2, 0, "%s", ptr + 1); 04615 } 04616 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04617 } else { 04618 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04619 } 04620 ast = ast_channel_unref(ast); 04621 } else { 04622 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04623 } 04624 } else { 04625 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04626 } 04627 04628 if (check_mime(vmu->fullname)) { 04629 int first_line = 1; 04630 char *ptr; 04631 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04632 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04633 *ptr = '\0'; 04634 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04635 first_line = 0; 04636 /* Substring is smaller, so this will never grow */ 04637 ast_str_set(&str2, 0, "%s", ptr + 1); 04638 } 04639 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04640 } else { 04641 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04642 } 04643 04644 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04645 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04646 struct ast_channel *ast; 04647 if ((ast = ast_dummy_channel_alloc())) { 04648 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04649 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04650 if (check_mime(ast_str_buffer(str1))) { 04651 int first_line = 1; 04652 char *ptr; 04653 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04654 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04655 *ptr = '\0'; 04656 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04657 first_line = 0; 04658 /* Substring is smaller, so this will never grow */ 04659 ast_str_set(&str2, 0, "%s", ptr + 1); 04660 } 04661 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04662 } else { 04663 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04664 } 04665 ast = ast_channel_unref(ast); 04666 } else { 04667 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04668 } 04669 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04670 if (ast_strlen_zero(flag)) { 04671 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04672 } else { 04673 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04674 } 04675 } else { 04676 if (ast_strlen_zero(flag)) { 04677 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04678 } else { 04679 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04680 } 04681 } 04682 04683 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04684 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04685 if (imap) { 04686 /* additional information needed for IMAP searching */ 04687 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04688 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04689 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04690 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04691 #ifdef IMAP_STORAGE 04692 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04693 #else 04694 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04695 #endif 04696 /* flag added for Urgent */ 04697 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04698 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04699 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04700 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04701 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04702 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04703 if (!ast_strlen_zero(category)) { 04704 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04705 } else { 04706 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04707 } 04708 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04709 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04710 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04711 } 04712 if (!ast_strlen_zero(cidnum)) { 04713 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04714 } 04715 if (!ast_strlen_zero(cidname)) { 04716 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04717 } 04718 fprintf(p, "MIME-Version: 1.0" ENDL); 04719 if (attach_user_voicemail) { 04720 /* Something unique. */ 04721 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04722 (int) getpid(), (unsigned int) ast_random()); 04723 04724 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04725 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04726 fprintf(p, "--%s" ENDL, bound); 04727 } 04728 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04729 if (emailbody || vmu->emailbody) { 04730 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04731 struct ast_channel *ast; 04732 if ((ast = ast_dummy_channel_alloc())) { 04733 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04734 ast_str_substitute_variables(&str1, 0, ast, e_body); 04735 #ifdef IMAP_STORAGE 04736 { 04737 /* Convert body to native line terminators for IMAP backend */ 04738 char *line = ast_str_buffer(str1), *next; 04739 do { 04740 /* Terminate line before outputting it to the file */ 04741 if ((next = strchr(line, '\n'))) { 04742 *next++ = '\0'; 04743 } 04744 fprintf(p, "%s" ENDL, line); 04745 line = next; 04746 } while (!ast_strlen_zero(line)); 04747 } 04748 #else 04749 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04750 #endif 04751 ast = ast_channel_unref(ast); 04752 } else { 04753 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04754 } 04755 } else if (msgnum > -1) { 04756 if (strcmp(vmu->mailbox, mailbox)) { 04757 /* Forwarded type */ 04758 struct ast_config *msg_cfg; 04759 const char *v; 04760 int inttime; 04761 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04762 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04763 /* Retrieve info from VM attribute file */ 04764 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04765 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04766 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04767 strcat(fromfile, ".txt"); 04768 } 04769 if ((msg_cfg = ast_config_load(fromfile, config_flags)) && valid_config(msg_cfg)) { 04770 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04771 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04772 } 04773 04774 /* You might be tempted to do origdate, except that a) it's in the wrong 04775 * format, and b) it's missing for IMAP recordings. */ 04776 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04777 struct timeval tv = { inttime, }; 04778 struct ast_tm tm; 04779 ast_localtime(&tv, &tm, NULL); 04780 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04781 } 04782 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04783 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04784 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04785 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04786 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04787 date, origcallerid, origdate); 04788 ast_config_destroy(msg_cfg); 04789 } else { 04790 goto plain_message; 04791 } 04792 } else { 04793 plain_message: 04794 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04795 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04796 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04797 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04798 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04799 } 04800 } else { 04801 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04802 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04803 } 04804 04805 if (imap || attach_user_voicemail) { 04806 if (!ast_strlen_zero(attach2)) { 04807 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04808 ast_debug(5, "creating second attachment filename %s\n", filename); 04809 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04810 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04811 ast_debug(5, "creating attachment filename %s\n", filename); 04812 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04813 } else { 04814 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04815 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04816 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04817 } 04818 } 04819 ast_free(str1); 04820 ast_free(str2); 04821 }
| 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 1676 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().
01677 { 01678 return snprintf(dest, len, "%s/msg%04d", dir, num); 01679 }
| static int manager_list_voicemail_users | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Manager list voicemail users command.
Definition at line 11685 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().
11686 { 11687 struct ast_vm_user *vmu = NULL; 11688 const char *id = astman_get_header(m, "ActionID"); 11689 char actionid[128] = ""; 11690 11691 if (!ast_strlen_zero(id)) 11692 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11693 11694 AST_LIST_LOCK(&users); 11695 11696 if (AST_LIST_EMPTY(&users)) { 11697 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11698 AST_LIST_UNLOCK(&users); 11699 return RESULT_SUCCESS; 11700 } 11701 11702 astman_send_ack(s, m, "Voicemail user list will follow"); 11703 11704 AST_LIST_TRAVERSE(&users, vmu, list) { 11705 char dirname[256]; 11706 11707 #ifdef IMAP_STORAGE 11708 int new, old; 11709 inboxcount(vmu->mailbox, &new, &old); 11710 #endif 11711 11712 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11713 astman_append(s, 11714 "%s" 11715 "Event: VoicemailUserEntry\r\n" 11716 "VMContext: %s\r\n" 11717 "VoiceMailbox: %s\r\n" 11718 "Fullname: %s\r\n" 11719 "Email: %s\r\n" 11720 "Pager: %s\r\n" 11721 "ServerEmail: %s\r\n" 11722 "MailCommand: %s\r\n" 11723 "Language: %s\r\n" 11724 "TimeZone: %s\r\n" 11725 "Callback: %s\r\n" 11726 "Dialout: %s\r\n" 11727 "UniqueID: %s\r\n" 11728 "ExitContext: %s\r\n" 11729 "SayDurationMinimum: %d\r\n" 11730 "SayEnvelope: %s\r\n" 11731 "SayCID: %s\r\n" 11732 "AttachMessage: %s\r\n" 11733 "AttachmentFormat: %s\r\n" 11734 "DeleteMessage: %s\r\n" 11735 "VolumeGain: %.2f\r\n" 11736 "CanReview: %s\r\n" 11737 "CallOperator: %s\r\n" 11738 "MaxMessageCount: %d\r\n" 11739 "MaxMessageLength: %d\r\n" 11740 "NewMessageCount: %d\r\n" 11741 #ifdef IMAP_STORAGE 11742 "OldMessageCount: %d\r\n" 11743 "IMAPUser: %s\r\n" 11744 #endif 11745 "\r\n", 11746 actionid, 11747 vmu->context, 11748 vmu->mailbox, 11749 vmu->fullname, 11750 vmu->email, 11751 vmu->pager, 11752 ast_strlen_zero(vmu->serveremail) ? serveremail : vmu->serveremail, 11753 mailcmd, 11754 vmu->language, 11755 vmu->zonetag, 11756 vmu->callback, 11757 vmu->dialout, 11758 vmu->uniqueid, 11759 vmu->exit, 11760 vmu->saydurationm, 11761 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11762 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11763 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11764 vmu->attachfmt, 11765 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11766 vmu->volgain, 11767 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11768 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11769 vmu->maxmsg, 11770 vmu->maxsecs, 11771 #ifdef IMAP_STORAGE 11772 new, old, vmu->imapuser 11773 #else 11774 count_messages(vmu, dirname) 11775 #endif 11776 ); 11777 } 11778 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11779 11780 AST_LIST_UNLOCK(&users); 11781 11782 return RESULT_SUCCESS; 11783 }
| static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11506 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().
11507 { 11508 while (poll_thread_run) { 11509 struct timespec ts = { 0, }; 11510 struct timeval wait; 11511 11512 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11513 ts.tv_sec = wait.tv_sec; 11514 ts.tv_nsec = wait.tv_usec * 1000; 11515 11516 ast_mutex_lock(&poll_lock); 11517 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11518 ast_mutex_unlock(&poll_lock); 11519 11520 if (!poll_thread_run) 11521 break; 11522 11523 poll_subscribed_mailboxes(); 11524 } 11525 11526 return NULL; 11527 }
| static const char* mbox | ( | struct ast_vm_user * | vmu, | |
| int | id | |||
| ) | [static] |
Definition at line 1737 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().
01738 { 01739 #ifdef IMAP_STORAGE 01740 if (vmu && id == 0) { 01741 return vmu->imapfolder; 01742 } 01743 #endif 01744 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01745 }
| static int messagecount | ( | const char * | context, | |
| const char * | mailbox, | |||
| const char * | folder | |||
| ) | [static] |
Definition at line 5404 of file app_voicemail.c.
References __has_voicemail().
Referenced by load_module().
05405 { 05406 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05407 }
| static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11529 of file app_voicemail.c.
References ast_free.
Referenced by handle_unsubscribe().
11530 { 11531 ast_free(mwi_sub); 11532 }
| static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 11617 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().
11618 { 11619 struct mwi_sub_task *mwist; 11620 11621 if (ast_event_get_type(event) != AST_EVENT_SUB) 11622 return; 11623 11624 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11625 return; 11626 11627 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11628 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11629 return; 11630 } 11631 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11632 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11633 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11634 11635 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11636 ast_free(mwist); 11637 } 11638 }
| static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 11591 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().
11592 { 11593 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11594 11595 if (!uniqueid) { 11596 ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); 11597 return; 11598 } 11599 11600 if (ast_event_get_type(event) != AST_EVENT_UNSUB) { 11601 ast_free(uniqueid); 11602 return; 11603 } 11604 11605 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { 11606 ast_free(uniqueid); 11607 return; 11608 } 11609 11610 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11611 *uniqueid = u; 11612 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11613 ast_free(uniqueid); 11614 } 11615 }
| 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 7090 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().
07091 { 07092 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07093 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07094 const char *category; 07095 char *myserveremail = serveremail; 07096 07097 ast_channel_lock(chan); 07098 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07099 category = ast_strdupa(category); 07100 } 07101 ast_channel_unlock(chan); 07102 07103 #ifndef IMAP_STORAGE 07104 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07105 #else 07106 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07107 #endif 07108 make_file(fn, sizeof(fn), todir, msgnum); 07109 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07110 07111 if (!ast_strlen_zero(vmu->attachfmt)) { 07112 if (strstr(fmt, vmu->attachfmt)) 07113 fmt = vmu->attachfmt; 07114 else 07115 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); 07116 } 07117 07118 /* Attach only the first format */ 07119 fmt = ast_strdupa(fmt); 07120 stringp = fmt; 07121 strsep(&stringp, "|"); 07122 07123 if (!ast_strlen_zero(vmu->serveremail)) 07124 myserveremail = vmu->serveremail; 07125 07126 if (!ast_strlen_zero(vmu->email)) { 07127 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07128 07129 if (attach_user_voicemail) 07130 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07131 07132 /* XXX possible imap issue, should category be NULL XXX */ 07133 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07134 07135 if (attach_user_voicemail) 07136 DISPOSE(todir, msgnum); 07137 } 07138 07139 if (!ast_strlen_zero(vmu->pager)) { 07140 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07141 } 07142 07143 if (ast_test_flag(vmu, VM_DELETE)) 07144 DELETE(todir, msgnum, fn, vmu); 07145 07146 /* Leave voicemail for someone */ 07147 if (ast_app_has_voicemail(ext_context, NULL)) 07148 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07149 07150 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07151 07152 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); 07153 run_externnotify(vmu->context, vmu->mailbox, flag); 07154 07155 #ifdef IMAP_STORAGE 07156 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07157 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07158 vm_imap_delete(NULL, vms->curmsg, vmu); 07159 vms->newmessages--; /* Fix new message count */ 07160 } 07161 #endif 07162 07163 return 0; 07164 }
| static int ochar | ( | struct baseio * | bio, | |
| int | c, | |||
| FILE * | so | |||
| ) | [static] |
utility used by base_encode()
Definition at line 4274 of file app_voicemail.c.
References BASELINELEN, ENDL, and baseio::linelength.
Referenced by base_encode().
04275 { 04276 if (bio->linelength >= BASELINELEN) { 04277 if (fputs(ENDL, so) == EOF) { 04278 return -1; 04279 } 04280 04281 bio->linelength = 0; 04282 } 04283 04284 if (putc(((unsigned char) c), so) == EOF) { 04285 return -1; 04286 } 04287 04288 bio->linelength++; 04289 04290 return 1; 04291 }
| static int open_mailbox | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu, | |||
| int | box | |||
| ) | [static] |
Definition at line 7939 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().
07940 { 07941 int count_msg, last_msg; 07942 07943 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07944 07945 /* Rename the member vmbox HERE so that we don't try to return before 07946 * we know what's going on. 07947 */ 07948 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07949 07950 /* Faster to make the directory than to check if it exists. */ 07951 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07952 07953 /* traverses directory using readdir (or select query for ODBC) */ 07954 count_msg = count_messages(vmu, vms->curdir); 07955 if (count_msg < 0) { 07956 return count_msg; 07957 } else { 07958 vms->lastmsg = count_msg - 1; 07959 } 07960 07961 if (vm_allocate_dh(vms, vmu, count_msg)) { 07962 return -1; 07963 } 07964 07965 /* 07966 The following test is needed in case sequencing gets messed up. 07967 There appears to be more than one way to mess up sequence, so 07968 we will not try to find all of the root causes--just fix it when 07969 detected. 07970 */ 07971 07972 if (vm_lock_path(vms->curdir)) { 07973 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07974 return ERROR_LOCK_PATH; 07975 } 07976 07977 /* for local storage, checks directory for messages up to maxmsg limit */ 07978 last_msg = last_message_index(vmu, vms->curdir); 07979 ast_unlock_path(vms->curdir); 07980 07981 if (last_msg < -1) { 07982 return last_msg; 07983 } else if (vms->lastmsg != last_msg) { 07984 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); 07985 resequence_mailbox(vmu, vms->curdir, count_msg); 07986 } 07987 07988 return 0; 07989 }
| static int play_message | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7713 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().
07714 { 07715 int res = 0; 07716 char filename[256], *cid; 07717 const char *origtime, *context, *category, *duration, *flag; 07718 struct ast_config *msg_cfg; 07719 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07720 07721 vms->starting = 0; 07722 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07723 adsi_message(chan, vms); 07724 if (!vms->curmsg) { 07725 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07726 } else if (vms->curmsg == vms->lastmsg) { 07727 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07728 } 07729 07730 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07731 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07732 msg_cfg = ast_config_load(filename, config_flags); 07733 if (!valid_config(msg_cfg)) { 07734 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07735 return 0; 07736 } 07737 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07738 07739 /* Play the word urgent if we are listening to urgent messages */ 07740 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07741 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07742 } 07743 07744 if (!res) { 07745 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07746 /* POLISH syntax */ 07747 if (!strncasecmp(chan->language, "pl", 2)) { 07748 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07749 int ten, one; 07750 char nextmsg[256]; 07751 ten = (vms->curmsg + 1) / 10; 07752 one = (vms->curmsg + 1) % 10; 07753 07754 if (vms->curmsg < 20) { 07755 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07756 res = wait_file2(chan, vms, nextmsg); 07757 } else { 07758 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07759 res = wait_file2(chan, vms, nextmsg); 07760 if (one > 0) { 07761 if (!res) { 07762 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07763 res = wait_file2(chan, vms, nextmsg); 07764 } 07765 } 07766 } 07767 } 07768 if (!res) 07769 res = wait_file2(chan, vms, "vm-message"); 07770 /* HEBREW syntax */ 07771 } else if (!strncasecmp(chan->language, "he", 2)) { 07772 if (!vms->curmsg) { 07773 res = wait_file2(chan, vms, "vm-message"); 07774 res = wait_file2(chan, vms, "vm-first"); 07775 } else if (vms->curmsg == vms->lastmsg) { 07776 res = wait_file2(chan, vms, "vm-message"); 07777 res = wait_file2(chan, vms, "vm-last"); 07778 } else { 07779 res = wait_file2(chan, vms, "vm-message"); 07780 res = wait_file2(chan, vms, "vm-number"); 07781 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07782 } 07783 /* VIETNAMESE syntax */ 07784 } else if (!strncasecmp(chan->language, "vi", 2)) { 07785 if (!vms->curmsg) { 07786 res = wait_file2(chan, vms, "vm-message"); 07787 res = wait_file2(chan, vms, "vm-first"); 07788 } else if (vms->curmsg == vms->lastmsg) { 07789 res = wait_file2(chan, vms, "vm-message"); 07790 res = wait_file2(chan, vms, "vm-last"); 07791 } else { 07792 res = wait_file2(chan, vms, "vm-message"); 07793 res = wait_file2(chan, vms, "vm-number"); 07794 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07795 } 07796 } else { 07797 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07798 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07799 } else { /* DEFAULT syntax */ 07800 res = wait_file2(chan, vms, "vm-message"); 07801 } 07802 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07803 if (!res) { 07804 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07805 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07806 } 07807 } 07808 } 07809 } 07810 07811 if (!valid_config(msg_cfg)) { 07812 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07813 return 0; 07814 } 07815 07816 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07817 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07818 DISPOSE(vms->curdir, vms->curmsg); 07819 ast_config_destroy(msg_cfg); 07820 return 0; 07821 } 07822 07823 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07824 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07825 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07826 07827 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07828 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07829 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07830 if (!res) { 07831 res = play_message_category(chan, category); 07832 } 07833 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07834 res = play_message_datetime(chan, vmu, origtime, filename); 07835 } 07836 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07837 res = play_message_callerid(chan, vms, cid, context, 0); 07838 } 07839 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07840 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07841 } 07842 /* Allow pressing '1' to skip envelope / callerid */ 07843 if (res == '1') { 07844 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07845 res = 0; 07846 } 07847 ast_config_destroy(msg_cfg); 07848 07849 if (!res) { 07850 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07851 #ifdef IMAP_STORAGE 07852 ast_mutex_lock(&vms->lock); 07853 #endif 07854 vms->heard[vms->curmsg] = 1; 07855 #ifdef IMAP_STORAGE 07856 ast_mutex_unlock(&vms->lock); 07857 /*IMAP storage stores any prepended message from a forward 07858 * as a separate file from the rest of the message 07859 */ 07860 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07861 wait_file(chan, vms, vms->introfn); 07862 } 07863 #endif 07864 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07865 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07866 res = 0; 07867 } 07868 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07869 } 07870 DISPOSE(vms->curdir, vms->curmsg); 07871 return res; 07872 }
| static int play_message_callerid | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | cid, | |||
| const char * | context, | |||
| int | callback | |||
| ) | [static] |
Definition at line 7599 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().
07600 { 07601 int res = 0; 07602 int i; 07603 char *callerid, *name; 07604 char prefile[PATH_MAX] = ""; 07605 07606 07607 /* If voicemail cid is not enabled, or we didn't get cid or context from 07608 * the attribute file, leave now. 07609 * 07610 * TODO Still need to change this so that if this function is called by the 07611 * message envelope (and someone is explicitly requesting to hear the CID), 07612 * it does not check to see if CID is enabled in the config file. 07613 */ 07614 if ((cid == NULL)||(context == NULL)) 07615 return res; 07616 07617 /* Strip off caller ID number from name */ 07618 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07619 ast_callerid_parse(cid, &name, &callerid); 07620 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07621 /* Check for internal contexts and only */ 07622 /* say extension when the call didn't come from an internal context in the list */ 07623 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07624 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07625 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07626 break; 07627 } 07628 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07629 if (!res) { 07630 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07631 if (!ast_strlen_zero(prefile)) { 07632 /* See if we can find a recorded name for this person instead of their extension number */ 07633 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07634 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07635 if (!callback) 07636 res = wait_file2(chan, vms, "vm-from"); 07637 res = ast_stream_and_wait(chan, prefile, ""); 07638 } else { 07639 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07640 /* Say "from extension" as one saying to sound smoother */ 07641 if (!callback) 07642 res = wait_file2(chan, vms, "vm-from-extension"); 07643 res = ast_say_digit_str(chan, callerid, "", chan->language); 07644 } 07645 } 07646 } 07647 } else if (!res) { 07648 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07649 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07650 if (!callback) 07651 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07652 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07653 } 07654 } else { 07655 /* Number unknown */ 07656 ast_debug(1, "VM-CID: From an unknown number\n"); 07657 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07658 res = wait_file2(chan, vms, "vm-unknown-caller"); 07659 } 07660 return res; 07661 }
| static int play_message_category | ( | struct ast_channel * | chan, | |
| const char * | category | |||
| ) | [static] |
Definition at line 7510 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
07511 { 07512 int res = 0; 07513 07514 if (!ast_strlen_zero(category)) 07515 res = ast_play_and_wait(chan, category); 07516 07517 if (res) { 07518 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07519 res = 0; 07520 } 07521 07522 return res; 07523 }
| static int play_message_datetime | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| const char * | origtime, | |||
| const char * | filename | |||
| ) | [static] |
Definition at line 7525 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().
07526 { 07527 int res = 0; 07528 struct vm_zone *the_zone = NULL; 07529 time_t t; 07530 07531 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07532 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07533 return 0; 07534 } 07535 07536 /* Does this user have a timezone specified? */ 07537 if (!ast_strlen_zero(vmu->zonetag)) { 07538 /* Find the zone in the list */ 07539 struct vm_zone *z; 07540 AST_LIST_LOCK(&zones); 07541 AST_LIST_TRAVERSE(&zones, z, list) { 07542 if (!strcmp(z->name, vmu->zonetag)) { 07543 the_zone = z; 07544 break; 07545 } 07546 } 07547 AST_LIST_UNLOCK(&zones); 07548 } 07549 07550 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07551 #if 0 07552 /* Set the DIFF_* variables */ 07553 ast_localtime(&t, &time_now, NULL); 07554 tv_now = ast_tvnow(); 07555 ast_localtime(&tv_now, &time_then, NULL); 07556 07557 /* Day difference */ 07558 if (time_now.tm_year == time_then.tm_year) 07559 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07560 else 07561 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07562 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07563 07564 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07565 #endif 07566 if (the_zone) { 07567 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07568 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07569 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07570 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07571 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07572 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07573 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); 07574 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07575 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07576 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07577 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07578 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07579 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07580 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07581 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); 07582 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07583 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07584 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07585 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07586 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07587 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); 07588 } else { 07589 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07590 } 07591 #if 0 07592 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07593 #endif 07594 return res; 07595 }
| static int play_message_duration | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| const char * | duration, | |||
| int | minduration | |||
| ) | [static] |
Definition at line 7663 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().
07664 { 07665 int res = 0; 07666 int durationm; 07667 int durations; 07668 /* Verify that we have a duration for the message */ 07669 if (duration == NULL) 07670 return res; 07671 07672 /* Convert from seconds to minutes */ 07673 durations = atoi(duration); 07674 durationm = (durations / 60); 07675 07676 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07677 07678 if ((!res) && (durationm >= minduration)) { 07679 res = wait_file2(chan, vms, "vm-duration"); 07680 07681 /* POLISH syntax */ 07682 if (!strncasecmp(chan->language, "pl", 2)) { 07683 div_t num = div(durationm, 10); 07684 07685 if (durationm == 1) { 07686 res = ast_play_and_wait(chan, "digits/1z"); 07687 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07688 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07689 if (num.rem == 2) { 07690 if (!num.quot) { 07691 res = ast_play_and_wait(chan, "digits/2-ie"); 07692 } else { 07693 res = say_and_wait(chan, durationm - 2 , chan->language); 07694 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07695 } 07696 } else { 07697 res = say_and_wait(chan, durationm, chan->language); 07698 } 07699 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07700 } else { 07701 res = say_and_wait(chan, durationm, chan->language); 07702 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07703 } 07704 /* DEFAULT syntax */ 07705 } else { 07706 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07707 res = wait_file2(chan, vms, "vm-minutes"); 07708 } 07709 } 07710 return res; 07711 }
| 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 13468 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().
13471 { 13472 /* Record message & let caller review or re-record it, or set options if applicable */ 13473 int res = 0; 13474 int cmd = 0; 13475 int max_attempts = 3; 13476 int attempts = 0; 13477 int recorded = 0; 13478 int msg_exists = 0; 13479 signed char zero_gain = 0; 13480 char tempfile[PATH_MAX]; 13481 char *acceptdtmf = "#"; 13482 char *canceldtmf = ""; 13483 int canceleddtmf = 0; 13484 13485 /* Note that urgent and private are for flagging messages as such in the future */ 13486 13487 /* barf if no pointer passed to store duration in */ 13488 if (duration == NULL) { 13489 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13490 return -1; 13491 } 13492 13493 if (!outsidecaller) 13494 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13495 else 13496 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13497 13498 cmd = '3'; /* Want to start by recording */ 13499 13500 while ((cmd >= 0) && (cmd != 't')) { 13501 switch (cmd) { 13502 case '1': 13503 if (!msg_exists) { 13504 /* In this case, 1 is to record a message */ 13505 cmd = '3'; 13506 break; 13507 } else { 13508 /* Otherwise 1 is to save the existing message */ 13509 ast_verb(3, "Saving message as is\n"); 13510 if (!outsidecaller) 13511 ast_filerename(tempfile, recordfile, NULL); 13512 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13513 if (!outsidecaller) { 13514 /* Saves to IMAP server only if imapgreeting=yes */ 13515 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13516 DISPOSE(recordfile, -1); 13517 } 13518 cmd = 't'; 13519 return res; 13520 } 13521 case '2': 13522 /* Review */ 13523 ast_verb(3, "Reviewing the message\n"); 13524 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13525 break; 13526 case '3': 13527 msg_exists = 0; 13528 /* Record */ 13529 if (recorded == 1) 13530 ast_verb(3, "Re-recording the message\n"); 13531 else 13532 ast_verb(3, "Recording the message\n"); 13533 13534 if (recorded && outsidecaller) { 13535 cmd = ast_play_and_wait(chan, INTRO); 13536 cmd = ast_play_and_wait(chan, "beep"); 13537 } 13538 recorded = 1; 13539 /* 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 */ 13540 if (record_gain) 13541 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13542 if (ast_test_flag(vmu, VM_OPERATOR)) 13543 canceldtmf = "0"; 13544 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13545 if (strchr(canceldtmf, cmd)) { 13546 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13547 canceleddtmf = 1; 13548 } 13549 if (record_gain) 13550 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13551 if (cmd == -1) { 13552 /* User has hung up, no options to give */ 13553 if (!outsidecaller) { 13554 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13555 ast_filedelete(tempfile, NULL); 13556 } 13557 return cmd; 13558 } 13559 if (cmd == '0') { 13560 break; 13561 } else if (cmd == '*') { 13562 break; 13563 #if 0 13564 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13565 /* Message is too short */ 13566 ast_verb(3, "Message too short\n"); 13567 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13568 cmd = ast_filedelete(tempfile, NULL); 13569 break; 13570 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13571 /* Message is all silence */ 13572 ast_verb(3, "Nothing recorded\n"); 13573 cmd = ast_filedelete(tempfile, NULL); 13574 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13575 if (!cmd) 13576 cmd = ast_play_and_wait(chan, "vm-speakup"); 13577 break; 13578 #endif 13579 } else { 13580 /* If all is well, a message exists */ 13581 msg_exists = 1; 13582 cmd = 0; 13583 } 13584 break; 13585 case '4': 13586 if (outsidecaller) { /* only mark vm messages */ 13587 /* Mark Urgent */ 13588 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13589 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13590 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13591 strcpy(flag, "Urgent"); 13592 } else if (flag) { 13593 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13594 res = ast_play_and_wait(chan, "vm-marked-nonurgent"); 13595 strcpy(flag, ""); 13596 } else { 13597 ast_play_and_wait(chan, "vm-sorry"); 13598 } 13599 cmd = 0; 13600 } else { 13601 cmd = ast_play_and_wait(chan, "vm-sorry"); 13602 } 13603 break; 13604 case '5': 13605 case '6': 13606 case '7': 13607 case '8': 13608 case '9': 13609 case '*': 13610 case '#': 13611 cmd = ast_play_and_wait(chan, "vm-sorry"); 13612 break; 13613 #if 0 13614 /* XXX Commented out for the moment because of the dangers of deleting 13615 a message while recording (can put the message numbers out of sync) */ 13616 case '*': 13617 /* Cancel recording, delete message, offer to take another message*/ 13618 cmd = ast_play_and_wait(chan, "vm-deleted"); 13619 cmd = ast_filedelete(tempfile, NULL); 13620 if (outsidecaller) { 13621 res = vm_exec(chan, NULL); 13622 return res; 13623 } 13624 else 13625 return 1; 13626 #endif 13627 case '0': 13628 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13629 cmd = ast_play_and_wait(chan, "vm-sorry"); 13630 break; 13631 } 13632 if (msg_exists || recorded) { 13633 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13634 if (!cmd) 13635 cmd = ast_waitfordigit(chan, 3000); 13636 if (cmd == '1') { 13637 ast_filerename(tempfile, recordfile, NULL); 13638 ast_play_and_wait(chan, "vm-msgsaved"); 13639 cmd = '0'; 13640 } else if (cmd == '4') { 13641 if (flag) { 13642 ast_play_and_wait(chan, "vm-marked-urgent"); 13643 strcpy(flag, "Urgent"); 13644 } 13645 ast_play_and_wait(chan, "vm-msgsaved"); 13646 cmd = '0'; 13647 } else { 13648 ast_play_and_wait(chan, "vm-deleted"); 13649 DELETE(tempfile, -1, tempfile, vmu); 13650 cmd = '0'; 13651 } 13652 } 13653 return cmd; 13654 default: 13655 /* If the caller is an ouside caller, and the review option is enabled, 13656 allow them to review the message, but let the owner of the box review 13657 their OGM's */ 13658 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13659 return cmd; 13660 if (msg_exists) { 13661 cmd = ast_play_and_wait(chan, "vm-review"); 13662 if (!cmd && outsidecaller) { 13663 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13664 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13665 } else if (flag) { 13666 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13667 } 13668 } 13669 } else { 13670 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13671 if (!cmd) 13672 cmd = ast_waitfordigit(chan, 600); 13673 } 13674 13675 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13676 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13677 if (!cmd) 13678 cmd = ast_waitfordigit(chan, 600); 13679 } 13680 #if 0 13681 if (!cmd) 13682 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13683 #endif 13684 if (!cmd) 13685 cmd = ast_waitfordigit(chan, 6000); 13686 if (!cmd) { 13687 attempts++; 13688 } 13689 if (attempts > max_attempts) { 13690 cmd = 't'; 13691 } 13692 } 13693 } 13694 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13695 /* Hang up or timeout, so delete the recording. */ 13696 ast_filedelete(tempfile, NULL); 13697 } 13698 13699 if (cmd != 't' && outsidecaller) 13700 ast_play_and_wait(chan, "vm-goodbye"); 13701 13702 return cmd; 13703 }
| static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11478 of file app_voicemail.c.
References inboxcount2(), queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11479 { 11480 int new = 0, old = 0, urgent = 0; 11481 11482 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11483 11484 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11485 mwi_sub->old_urgent = urgent; 11486 mwi_sub->old_new = new; 11487 mwi_sub->old_old = old; 11488 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11489 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11490 } 11491 }
| static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11493 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().
11494 { 11495 struct mwi_sub *mwi_sub; 11496 11497 AST_RWLIST_RDLOCK(&mwi_subs); 11498 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11499 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11500 poll_subscribed_mailbox(mwi_sub); 11501 } 11502 } 11503 AST_RWLIST_UNLOCK(&mwi_subs); 11504 }
| 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 1021 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().
01022 { 01023 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 01024 vmu->passwordlocation = passwordlocation; 01025 if (saydurationminfo) { 01026 vmu->saydurationm = saydurationminfo; 01027 } 01028 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 01029 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 01030 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 01031 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 01032 ast_copy_string(vmu->locale, locale, sizeof(vmu->locale)); 01033 if (vmminsecs) { 01034 vmu->minsecs = vmminsecs; 01035 } 01036 if (vmmaxsecs) { 01037 vmu->maxsecs = vmmaxsecs; 01038 } 01039 if (maxmsg) { 01040 vmu->maxmsg = maxmsg; 01041 } 01042 if (maxdeletedmsg) { 01043 vmu->maxdeletedmsg = maxdeletedmsg; 01044 } 01045 vmu->volgain = volgain; 01046 ast_free(vmu->emailsubject); 01047 vmu->emailsubject = NULL; 01048 ast_free(vmu->emailbody); 01049 vmu->emailbody = NULL; 01050 #ifdef IMAP_STORAGE 01051 ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder)); 01052 #endif 01053 }
| 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 4362 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().
04363 { 04364 char callerid[256]; 04365 char num[12]; 04366 char fromdir[256], fromfile[256]; 04367 struct ast_config *msg_cfg; 04368 const char *origcallerid, *origtime; 04369 char origcidname[80], origcidnum[80], origdate[80]; 04370 int inttime; 04371 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04372 04373 /* Prepare variables for substitution in email body and subject */ 04374 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04375 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04376 snprintf(num, sizeof(num), "%d", msgnum); 04377 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04378 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04379 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04380 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04381 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04382 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04383 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04384 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04385 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04386 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04387 04388 /* Retrieve info from VM attribute file */ 04389 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04390 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04391 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04392 strcat(fromfile, ".txt"); 04393 } 04394 if (!(msg_cfg = ast_config_load(fromfile, config_flags)) || !(valid_config(msg_cfg))) { 04395 if (option_debug > 0) { 04396 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04397 } 04398 return; 04399 } 04400 04401 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04402 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04403 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04404 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04405 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04406 } 04407 04408 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04409 struct timeval tv = { inttime, }; 04410 struct ast_tm tm; 04411 ast_localtime(&tv, &tm, NULL); 04412 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04413 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04414 } 04415 ast_config_destroy(msg_cfg); 04416 }
| static void queue_mwi_event | ( | const char * | box, | |
| int | urgent, | |||
| int | new, | |||
| int | old | |||
| ) | [static] |
Definition at line 7053 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().
07054 { 07055 struct ast_event *event; 07056 char *mailbox, *context; 07057 07058 /* Strip off @default */ 07059 context = mailbox = ast_strdupa(box); 07060 strsep(&context, "@"); 07061 if (ast_strlen_zero(context)) 07062 context = "default"; 07063 07064 if (!(event = ast_event_new(AST_EVENT_MWI, 07065 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 07066 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 07067 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 07068 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 07069 AST_EVENT_IE_END))) { 07070 return; 07071 } 07072 07073 ast_event_queue_and_cache(event); 07074 }
| static void read_password_from_file | ( | const char * | secretfn, | |
| char * | password, | |||
| int | passwordlen | |||
| ) | [static] |
Definition at line 12584 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().
12584 { 12585 struct ast_config *pwconf; 12586 struct ast_flags config_flags = { 0 }; 12587 12588 pwconf = ast_config_load(secretfn, config_flags); 12589 if (valid_config(pwconf)) { 12590 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12591 if (val) { 12592 ast_copy_string(password, val, passwordlen); 12593 ast_config_destroy(pwconf); 12594 return; 12595 } 12596 ast_config_destroy(pwconf); 12597 } 12598 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12599 }
| static int reload | ( | void | ) | [static] |
Definition at line 13115 of file app_voicemail.c.
References load_config().
13116 { 13117 return load_config(1); 13118 }
| 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 4032 of file app_voicemail.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
04033 { 04034 char stxt[PATH_MAX]; 04035 char dtxt[PATH_MAX]; 04036 ast_filerename(sfn, dfn, NULL); 04037 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 04038 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 04039 if (ast_check_realtime("voicemail_data")) { 04040 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 04041 } 04042 rename(stxt, dtxt); 04043 }
| static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
| char * | dir, | |||
| int | stopcount | |||
| ) | [static] |
Definition at line 6179 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().
06180 { 06181 /* we know the actual number of messages, so stop process when number is hit */ 06182 06183 int x, dest; 06184 char sfn[PATH_MAX]; 06185 char dfn[PATH_MAX]; 06186 06187 if (vm_lock_path(dir)) { 06188 return ERROR_LOCK_PATH; 06189 } 06190 06191 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06192 make_file(sfn, sizeof(sfn), dir, x); 06193 if (EXISTS(dir, x, sfn, NULL)) { 06194 06195 if (x != dest) { 06196 make_file(dfn, sizeof(dfn), dir, dest); 06197 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06198 } 06199 06200 dest++; 06201 } 06202 } 06203 ast_unlock_path(dir); 06204 06205 return dest; 06206 }
| 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 1491 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().
01492 { 01493 /* This function could be made to generate one from a database, too */ 01494 struct ast_vm_user *cur; 01495 int res = -1; 01496 AST_LIST_LOCK(&users); 01497 AST_LIST_TRAVERSE(&users, cur, list) { 01498 if ((!context || !strcasecmp(context, cur->context)) && 01499 (!strcasecmp(mailbox, cur->mailbox))) 01500 break; 01501 } 01502 if (cur) { 01503 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01504 res = 0; 01505 } 01506 AST_LIST_UNLOCK(&users); 01507 return res; 01508 }
| static void run_externnotify | ( | char * | context, | |
| char * | extension, | |||
| const char * | flag | |||
| ) | [static] |
Definition at line 5547 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().
05548 { 05549 char arguments[255]; 05550 char ext_context[256] = ""; 05551 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05552 struct ast_smdi_mwi_message *mwi_msg; 05553 05554 if (!ast_strlen_zero(context)) 05555 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05556 else 05557 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05558 05559 if (smdi_iface) { 05560 if (ast_app_has_voicemail(ext_context, NULL)) 05561 ast_smdi_mwi_set(smdi_iface, extension); 05562 else 05563 ast_smdi_mwi_unset(smdi_iface, extension); 05564 05565 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05566 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05567 if (!strncmp(mwi_msg->cause, "INV", 3)) 05568 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05569 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05570 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05571 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05572 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05573 } else { 05574 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05575 } 05576 } 05577 05578 if (!ast_strlen_zero(externnotify)) { 05579 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05580 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05581 } else { 05582 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", 05583 externnotify, S_OR(context, "\"\""), 05584 extension, newvoicemails, 05585 oldvoicemails, urgentvoicemails); 05586 ast_debug(1, "Executing %s\n", arguments); 05587 ast_safe_system(arguments); 05588 } 05589 } 05590 }
| static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
| struct vm_state * | vms, | |||
| int | msg, | |||
| int | box | |||
| ) | [static] |
Definition at line 6216 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().
06217 { 06218 #ifdef IMAP_STORAGE 06219 /* we must use mbox(x) folder names, and copy the message there */ 06220 /* simple. huh? */ 06221 char sequence[10]; 06222 char mailbox[256]; 06223 int res; 06224 06225 /* get the real IMAP message number for this message */ 06226 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06227 06228 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06229 ast_mutex_lock(&vms->lock); 06230 /* if save to Old folder, put in INBOX as read */ 06231 if (box == OLD_FOLDER) { 06232 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06233 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06234 } else if (box == NEW_FOLDER) { 06235 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06236 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06237 } 06238 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06239 ast_mutex_unlock(&vms->lock); 06240 return 0; 06241 } 06242 /* Create the folder if it don't exist */ 06243 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06244 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06245 if (mail_create(vms->mailstream, mailbox) == NIL) 06246 ast_debug(5, "Folder exists.\n"); 06247 else 06248 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06249 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06250 ast_mutex_unlock(&vms->lock); 06251 return res; 06252 #else 06253 char *dir = vms->curdir; 06254 char *username = vms->username; 06255 char *context = vmu->context; 06256 char sfn[PATH_MAX]; 06257 char dfn[PATH_MAX]; 06258 char ddir[PATH_MAX]; 06259 const char *dbox = mbox(vmu, box); 06260 int x, i; 06261 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06262 06263 if (vm_lock_path(ddir)) 06264 return ERROR_LOCK_PATH; 06265 06266 x = last_message_index(vmu, ddir) + 1; 06267 06268 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06269 x--; 06270 for (i = 1; i <= x; i++) { 06271 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06272 make_file(sfn, sizeof(sfn), ddir, i); 06273 make_file(dfn, sizeof(dfn), ddir, i - 1); 06274 if (EXISTS(ddir, i, sfn, NULL)) { 06275 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06276 } else 06277 break; 06278 } 06279 } else { 06280 if (x >= vmu->maxmsg) { 06281 ast_unlock_path(ddir); 06282 return -1; 06283 } 06284 } 06285 make_file(sfn, sizeof(sfn), dir, msg); 06286 make_file(dfn, sizeof(dfn), ddir, x); 06287 if (strcmp(sfn, dfn)) { 06288 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06289 } 06290 ast_unlock_path(ddir); 06291 #endif 06292 return 0; 06293 }
| static int say_and_wait | ( | struct ast_channel * | chan, | |
| int | num, | |||
| const char * | language | |||
| ) | [static] |
Definition at line 6209 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().
06210 { 06211 int d; 06212 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06213 return d; 06214 }
| static int sayname | ( | struct ast_channel * | chan, | |
| const char * | mailbox, | |||
| const char * | context | |||
| ) | [static] |
Definition at line 12570 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().
12571 { 12572 int res = -1; 12573 char dir[PATH_MAX]; 12574 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12575 ast_debug(2, "About to try retrieving name file %s\n", dir); 12576 RETRIEVE(dir, -1, mailbox, context); 12577 if (ast_fileexists(dir, NULL, NULL)) { 12578 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12579 } 12580 DISPOSE(dir, -1); 12581 return res; 12582 }
| 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 4877 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().
04878 { 04879 FILE *p = NULL; 04880 char tmp[80] = "/tmp/astmail-XXXXXX"; 04881 char tmp2[256]; 04882 char *stringp; 04883 04884 if (vmu && ast_strlen_zero(vmu->email)) { 04885 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04886 return(0); 04887 } 04888 04889 /* Mail only the first format */ 04890 format = ast_strdupa(format); 04891 stringp = format; 04892 strsep(&stringp, "|"); 04893 04894 if (!strcmp(format, "wav49")) 04895 format = "WAV"; 04896 ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH)); 04897 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04898 command hangs */ 04899 if ((p = vm_mkftemp(tmp)) == NULL) { 04900 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04901 return -1; 04902 } else { 04903 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04904 fclose(p); 04905 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04906 ast_safe_system(tmp2); 04907 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04908 } 04909 return 0; 04910 }
| 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 4912 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().
04913 { 04914 char enc_cidnum[256], enc_cidname[256]; 04915 char date[256]; 04916 char host[MAXHOSTNAMELEN] = ""; 04917 char who[256]; 04918 char dur[PATH_MAX]; 04919 char tmp[80] = "/tmp/astmail-XXXXXX"; 04920 char tmp2[PATH_MAX]; 04921 struct ast_tm tm; 04922 FILE *p; 04923 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04924 04925 if (!str1 || !str2) { 04926 ast_free(str1); 04927 ast_free(str2); 04928 return -1; 04929 } 04930 04931 if (cidnum) { 04932 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04933 } 04934 if (cidname) { 04935 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04936 } 04937 04938 if ((p = vm_mkftemp(tmp)) == NULL) { 04939 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04940 ast_free(str1); 04941 ast_free(str2); 04942 return -1; 04943 } 04944 gethostname(host, sizeof(host)-1); 04945 if (strchr(srcemail, '@')) { 04946 ast_copy_string(who, srcemail, sizeof(who)); 04947 } else { 04948 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04949 } 04950 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04951 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04952 fprintf(p, "Date: %s\n", date); 04953 04954 /* Reformat for custom pager format */ 04955 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04956 04957 if (!ast_strlen_zero(pagerfromstring)) { 04958 struct ast_channel *ast; 04959 if ((ast = ast_dummy_channel_alloc())) { 04960 char *ptr; 04961 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04962 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04963 04964 if (check_mime(ast_str_buffer(str1))) { 04965 int first_line = 1; 04966 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04967 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04968 *ptr = '\0'; 04969 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04970 first_line = 0; 04971 /* Substring is smaller, so this will never grow */ 04972 ast_str_set(&str2, 0, "%s", ptr + 1); 04973 } 04974 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04975 } else { 04976 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04977 } 04978 ast = ast_channel_unref(ast); 04979 } else { 04980 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04981 } 04982 } else { 04983 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04984 } 04985 04986 if (check_mime(vmu->fullname)) { 04987 int first_line = 1; 04988 char *ptr; 04989 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04990 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04991 *ptr = '\0'; 04992 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04993 first_line = 0; 04994 /* Substring is smaller, so this will never grow */ 04995 ast_str_set(&str2, 0, "%s", ptr + 1); 04996 } 04997 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04998 } else { 04999 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 05000 } 05001 05002 if (!ast_strlen_zero(pagersubject)) { 05003 struct ast_channel *ast; 05004 if ((ast = ast_dummy_channel_alloc())) { 05005 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05006 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 05007 if (check_mime(ast_str_buffer(str1))) { 05008 int first_line = 1; 05009 char *ptr; 05010 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 05011 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 05012 *ptr = '\0'; 05013 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 05014 first_line = 0; 05015 /* Substring is smaller, so this will never grow */ 05016 ast_str_set(&str2, 0, "%s", ptr + 1); 05017 } 05018 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 05019 } else { 05020 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 05021 } 05022 ast = ast_channel_unref(ast); 05023 } else { 05024 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05025 } 05026 } else { 05027 if (ast_strlen_zero(flag)) { 05028 fprintf(p, "Subject: New VM\n\n"); 05029 } else { 05030 fprintf(p, "Subject: New %s VM\n\n", flag); 05031 } 05032 } 05033 05034 if (pagerbody) { 05035 struct ast_channel *ast; 05036 if ((ast = ast_dummy_channel_alloc())) { 05037 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05038 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 05039 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 05040 ast = ast_channel_unref(ast); 05041 } else { 05042 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05043 } 05044 } else { 05045 fprintf(p, "New %s long %s msg in box %s\n" 05046 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 05047 } 05048 05049 fclose(p); 05050 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 05051 ast_safe_system(tmp2); 05052 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 05053 ast_free(str1); 05054 ast_free(str2); 05055 return 0; 05056 }
| static char* show_users_realtime | ( | int | fd, | |
| const char * | context | |||
| ) | [static] |
Definition at line 11135 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().
11136 { 11137 struct ast_config *cfg; 11138 const char *cat = NULL; 11139 11140 if (!(cfg = ast_load_realtime_multientry("voicemail", 11141 "context", context, SENTINEL))) { 11142 return CLI_FAILURE; 11143 } 11144 11145 ast_cli(fd, 11146 "\n" 11147 "=============================================================\n" 11148 "=== Configured Voicemail Users ==============================\n" 11149 "=============================================================\n" 11150 "===\n"); 11151 11152 while ((cat = ast_category_browse(cfg, cat))) { 11153 struct ast_variable *var = NULL; 11154 ast_cli(fd, 11155 "=== Mailbox ...\n" 11156 "===\n"); 11157 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11158 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11159 ast_cli(fd, 11160 "===\n" 11161 "=== ---------------------------------------------------------\n" 11162 "===\n"); 11163 } 11164 11165 ast_cli(fd, 11166 "=============================================================\n" 11167 "\n"); 11168 11169 ast_config_destroy(cfg); 11170 11171 return CLI_SUCCESS; 11172 }
| static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11640 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().
11641 { 11642 int errcode; 11643 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11644 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11645 AST_EVENT_IE_END); 11646 11647 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11648 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11649 AST_EVENT_IE_END); 11650 11651 if (mwi_sub_sub) 11652 ast_event_report_subs(mwi_sub_sub); 11653 11654 poll_thread_run = 1; 11655 11656 if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) { 11657 ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode)); 11658 } 11659 }
| static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11661 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().
11662 { 11663 poll_thread_run = 0; 11664 11665 if (mwi_sub_sub) { 11666 ast_event_unsubscribe(mwi_sub_sub); 11667 mwi_sub_sub = NULL; 11668 } 11669 11670 if (mwi_unsub_sub) { 11671 ast_event_unsubscribe(mwi_unsub_sub); 11672 mwi_unsub_sub = NULL; 11673 } 11674 11675 ast_mutex_lock(&poll_lock); 11676 ast_cond_signal(&poll_cond); 11677 ast_mutex_unlock(&poll_lock); 11678 11679 pthread_join(poll_thread, NULL); 11680 11681 poll_thread = AST_PTHREADT_NULL; 11682 }
| 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 991 of file app_voicemail.c.
Referenced by make_email_file(), and sendpage().
| static const char * substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 11807 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().
11808 { 11809 char *current; 11810 11811 /* Add 16 for fudge factor */ 11812 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11813 11814 ast_str_reset(str); 11815 11816 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11817 for (current = (char *) value; *current; current++) { 11818 if (*current == '\\') { 11819 current++; 11820 if (!*current) { 11821 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11822 break; 11823 } 11824 switch (*current) { 11825 case '\\': 11826 ast_str_append(&str, 0, "\\"); 11827 break; 11828 case 'r': 11829 ast_str_append(&str, 0, "\r"); 11830 break; 11831 case 'n': 11832 #ifdef IMAP_STORAGE 11833 if (!str->used || str->str[str->used - 1] != '\r') { 11834 ast_str_append(&str, 0, "\r"); 11835 } 11836 #endif 11837 ast_str_append(&str, 0, "\n"); 11838 break; 11839 case 't': 11840 ast_str_append(&str, 0, "\t"); 11841 break; 11842 default: 11843 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11844 break; 11845 } 11846 } else { 11847 ast_str_append(&str, 0, "%c", *current); 11848 } 11849 } 11850 11851 return ast_str_buffer(str); 11852 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 13120 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().
13121 { 13122 int res; 13123 13124 res = ast_unregister_application(app); 13125 res |= ast_unregister_application(app2); 13126 res |= ast_unregister_application(app3); 13127 res |= ast_unregister_application(app4); 13128 res |= ast_unregister_application(sayname_app); 13129 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13130 res |= ast_manager_unregister("VoicemailUsersList"); 13131 res |= ast_data_unregister(NULL); 13132 #ifdef TEST_FRAMEWORK 13133 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13134 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13135 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13136 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13137 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13138 #endif 13139 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13140 ast_uninstall_vm_functions(); 13141 ao2_ref(inprocess_container, -1); 13142 13143 if (poll_thread != AST_PTHREADT_NULL) 13144 stop_poll_thread(); 13145 13146 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13147 ast_unload_realtime("voicemail"); 13148 ast_unload_realtime("voicemail_data"); 13149 13150 free_vm_users(); 13151 free_vm_zones(); 13152 return res; 13153 }
| static int valid_config | ( | const struct ast_config * | cfg | ) | [inline, static] |
Check if configuration file is valid.
Definition at line 1513 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().
01514 { 01515 return cfg && cfg != CONFIG_STATUS_FILEINVALID; 01516 }
| static int vm_allocate_dh | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu, | |||
| int | count_msg | |||
| ) | [static] |
Definition at line 1774 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().
01774 { 01775 01776 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01777 01778 /* remove old allocation */ 01779 if (vms->deleted) { 01780 ast_free(vms->deleted); 01781 vms->deleted = NULL; 01782 } 01783 if (vms->heard) { 01784 ast_free(vms->heard); 01785 vms->heard = NULL; 01786 } 01787 vms->dh_arraysize = 0; 01788 01789 if (arraysize > 0) { 01790 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01791 return -1; 01792 } 01793 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01794 ast_free(vms->deleted); 01795 vms->deleted = NULL; 01796 return -1; 01797 } 01798 vms->dh_arraysize = arraysize; 01799 } 01800 01801 return 0; 01802 }
| 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 9811 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_test_suite_event_notify, 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().
09814 { 09815 int useadsi = 0, valid = 0, logretries = 0; 09816 char password[AST_MAX_EXTENSION]="", *passptr; 09817 struct ast_vm_user vmus, *vmu = NULL; 09818 09819 /* If ADSI is supported, setup login screen */ 09820 adsi_begin(chan, &useadsi); 09821 if (!skipuser && useadsi) 09822 adsi_login(chan); 09823 ast_test_suite_event_notify("PLAYBACK", "Message: vm-login"); 09824 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09825 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09826 return -1; 09827 } 09828 09829 /* Authenticate them and get their mailbox/password */ 09830 09831 while (!valid && (logretries < max_logins)) { 09832 /* Prompt for, and read in the username */ 09833 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09834 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09835 return -1; 09836 } 09837 if (ast_strlen_zero(mailbox)) { 09838 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09839 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09840 } else { 09841 ast_verb(3, "Username not entered\n"); 09842 return -1; 09843 } 09844 } else if (mailbox[0] == '*') { 09845 /* user entered '*' */ 09846 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09847 if (ast_exists_extension(chan, chan->context, "a", 1, 09848 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09849 return -1; 09850 } 09851 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09852 mailbox[0] = '\0'; 09853 } 09854 09855 if (useadsi) 09856 adsi_password(chan); 09857 09858 if (!ast_strlen_zero(prefix)) { 09859 char fullusername[80] = ""; 09860 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09861 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09862 ast_copy_string(mailbox, fullusername, mailbox_size); 09863 } 09864 09865 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09866 vmu = find_user(&vmus, context, mailbox); 09867 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09868 /* saved password is blank, so don't bother asking */ 09869 password[0] = '\0'; 09870 } else { 09871 ast_test_suite_event_notify("PLAYBACK", "Message: %s", vm_password); 09872 if (ast_streamfile(chan, vm_password, chan->language)) { 09873 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09874 return -1; 09875 } 09876 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09877 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09878 return -1; 09879 } else if (password[0] == '*') { 09880 /* user entered '*' */ 09881 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09882 if (ast_exists_extension(chan, chan->context, "a", 1, 09883 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09884 mailbox[0] = '*'; 09885 return -1; 09886 } 09887 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09888 mailbox[0] = '\0'; 09889 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09890 vmu = NULL; 09891 } 09892 } 09893 09894 if (vmu) { 09895 passptr = vmu->password; 09896 if (passptr[0] == '-') passptr++; 09897 } 09898 if (vmu && !strcmp(passptr, password)) 09899 valid++; 09900 else { 09901 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09902 if (!ast_strlen_zero(prefix)) 09903 mailbox[0] = '\0'; 09904 } 09905 logretries++; 09906 if (!valid) { 09907 if (skipuser || logretries >= max_logins) { 09908 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect"); 09909 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09910 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09911 return -1; 09912 } 09913 } else { 09914 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect-mailbox"); 09915 if (useadsi) 09916 adsi_login(chan); 09917 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09918 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09919 return -1; 09920 } 09921 } 09922 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09923 return -1; 09924 } 09925 } 09926 if (!valid && (logretries >= max_logins)) { 09927 ast_stopstream(chan); 09928 ast_play_and_wait(chan, "vm-goodbye"); 09929 return -1; 09930 } 09931 if (vmu && !skipuser) { 09932 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09933 } 09934 return 0; 09935 }
| static int vm_box_exists | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 11030 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().
11031 { 11032 struct ast_vm_user svm; 11033 char *context, *box; 11034 AST_DECLARE_APP_ARGS(args, 11035 AST_APP_ARG(mbox); 11036 AST_APP_ARG(options); 11037 ); 11038 static int dep_warning = 0; 11039 11040 if (ast_strlen_zero(data)) { 11041 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 11042 return -1; 11043 } 11044 11045 if (!dep_warning) { 11046 dep_warning = 1; 11047 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 11048 } 11049 11050 box = ast_strdupa(data); 11051 11052 AST_STANDARD_APP_ARGS(args, box); 11053 11054 if (args.options) { 11055 } 11056 11057 if ((context = strchr(args.mbox, '@'))) { 11058 *context = '\0'; 11059 context++; 11060 } 11061 11062 if (find_user(&svm, context, args.mbox)) { 11063 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11064 } else 11065 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11066 11067 return 0; 11068 }
| 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 9790 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().
09791 { 09792 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09793 return vm_browse_messages_es(chan, vms, vmu); 09794 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09795 return vm_browse_messages_gr(chan, vms, vmu); 09796 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09797 return vm_browse_messages_he(chan, vms, vmu); 09798 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09799 return vm_browse_messages_it(chan, vms, vmu); 09800 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09801 return vm_browse_messages_pt(chan, vms, vmu); 09802 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09803 return vm_browse_messages_vi(chan, vms, vmu); 09804 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09805 return vm_browse_messages_zh(chan, vms, vmu); 09806 } else { /* Default to English syntax */ 09807 return vm_browse_messages_en(chan, vms, vmu); 09808 } 09809 }
| 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 9629 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().
09630 { 09631 int cmd = 0; 09632 09633 if (vms->lastmsg > -1) { 09634 cmd = play_message(chan, vmu, vms); 09635 } else { 09636 cmd = ast_play_and_wait(chan, "vm-youhave"); 09637 if (!cmd) 09638 cmd = ast_play_and_wait(chan, "vm-no"); 09639 if (!cmd) { 09640 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09641 cmd = ast_play_and_wait(chan, vms->fn); 09642 } 09643 if (!cmd) 09644 cmd = ast_play_and_wait(chan, "vm-messages"); 09645 } 09646 return cmd; 09647 }
| 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 9683 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().
09684 { 09685 int cmd; 09686 09687 if (vms->lastmsg > -1) { 09688 cmd = play_message(chan, vmu, vms); 09689 } else { 09690 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09691 if (!cmd) 09692 cmd = ast_play_and_wait(chan, "vm-messages"); 09693 if (!cmd) { 09694 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09695 cmd = ast_play_and_wait(chan, vms->fn); 09696 } 09697 } 09698 return cmd; 09699 }
| 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 9577 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().
09578 { 09579 int cmd = 0; 09580 09581 if (vms->lastmsg > -1) { 09582 cmd = play_message(chan, vmu, vms); 09583 } else { 09584 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09585 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09586 if (!cmd) { 09587 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09588 cmd = ast_play_and_wait(chan, vms->fn); 09589 } 09590 if (!cmd) 09591 cmd = ast_play_and_wait(chan, "vm-messages"); 09592 } else { 09593 if (!cmd) 09594 cmd = ast_play_and_wait(chan, "vm-messages"); 09595 if (!cmd) { 09596 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09597 cmd = ast_play_and_wait(chan, vms->fn); 09598 } 09599 } 09600 } 09601 return cmd; 09602 }
| static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| struct ast_vm_user * | vmu | |||
| ) | [static] |
Definition at line 9605 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09606 { 09607 int cmd = 0; 09608 09609 if (vms->lastmsg > -1) { 09610 cmd = play_message(chan, vmu, vms); 09611 } else { 09612 if (!strcasecmp(vms->fn, "INBOX")) { 09613 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09614 } else { 09615 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09616 } 09617 } 09618 return cmd; 09619 }
| 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 9657 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().
09658 { 09659 int cmd; 09660 09661 if (vms->lastmsg > -1) { 09662 cmd = play_message(chan, vmu, vms); 09663 } else { 09664 cmd = ast_play_and_wait(chan, "vm-no"); 09665 if (!cmd) 09666 cmd = ast_play_and_wait(chan, "vm-message"); 09667 if (!cmd) { 09668 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09669 cmd = ast_play_and_wait(chan, vms->fn); 09670 } 09671 } 09672 return cmd; 09673 }
| 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 9709 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().
09710 { 09711 int cmd; 09712 09713 if (vms->lastmsg > -1) { 09714 cmd = play_message(chan, vmu, vms); 09715 } else { 09716 cmd = ast_play_and_wait(chan, "vm-no"); 09717 if (!cmd) { 09718 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09719 cmd = ast_play_and_wait(chan, vms->fn); 09720 } 09721 if (!cmd) 09722 cmd = ast_play_and_wait(chan, "vm-messages"); 09723 } 09724 return cmd; 09725 }
| 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 9763 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().
09764 { 09765 int cmd = 0; 09766 09767 if (vms->lastmsg > -1) { 09768 cmd = play_message(chan, vmu, vms); 09769 } else { 09770 cmd = ast_play_and_wait(chan, "vm-no"); 09771 if (!cmd) { 09772 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09773 cmd = ast_play_and_wait(chan, vms->fn); 09774 } 09775 } 09776 return cmd; 09777 }
| 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 9735 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().
09736 { 09737 int cmd; 09738 09739 if (vms->lastmsg > -1) { 09740 cmd = play_message(chan, vmu, vms); 09741 } else { 09742 cmd = ast_play_and_wait(chan, "vm-you"); 09743 if (!cmd) 09744 cmd = ast_play_and_wait(chan, "vm-haveno"); 09745 if (!cmd) 09746 cmd = ast_play_and_wait(chan, "vm-messages"); 09747 if (!cmd) { 09748 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09749 cmd = ast_play_and_wait(chan, vms->fn); 09750 } 09751 } 09752 return cmd; 09753 }
| 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 1525 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().
01526 { 01527 struct ast_config *cfg = NULL; 01528 struct ast_variable *var = NULL; 01529 struct ast_category *cat = NULL; 01530 char *category = NULL, *value = NULL, *new = NULL; 01531 const char *tmp = NULL; 01532 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01533 char secretfn[PATH_MAX] = ""; 01534 int found = 0; 01535 01536 if (!change_password_realtime(vmu, newpassword)) 01537 return; 01538 01539 /* check if we should store the secret in the spool directory next to the messages */ 01540 switch (vmu->passwordlocation) { 01541 case OPT_PWLOC_SPOOLDIR: 01542 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01543 if (write_password_to_file(secretfn, newpassword) == 0) { 01544 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf"); 01545 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01546 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01547 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01548 break; 01549 } else { 01550 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01551 } 01552 /* Fall-through */ 01553 case OPT_PWLOC_VOICEMAILCONF: 01554 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && valid_config(cfg)) { 01555 while ((category = ast_category_browse(cfg, category))) { 01556 if (!strcasecmp(category, vmu->context)) { 01557 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01558 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01559 break; 01560 } 01561 value = strstr(tmp, ","); 01562 if (!value) { 01563 new = ast_alloca(strlen(newpassword)+1); 01564 sprintf(new, "%s", newpassword); 01565 } else { 01566 new = ast_alloca((strlen(value) + strlen(newpassword) + 1)); 01567 sprintf(new, "%s%s", newpassword, value); 01568 } 01569 if (!(cat = ast_category_get(cfg, category))) { 01570 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01571 break; 01572 } 01573 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01574 found = 1; 01575 } 01576 } 01577 /* save the results */ 01578 if (found) { 01579 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf"); 01580 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01581 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01582 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01583 ast_config_destroy(cfg); 01584 break; 01585 } 01586 01587 ast_config_destroy(cfg); 01588 } 01589 /* Fall-through */ 01590 case OPT_PWLOC_USERSCONF: 01591 /* check users.conf and update the password stored for the mailbox */ 01592 /* if no vmsecret entry exists create one. */ 01593 if ((cfg = ast_config_load("users.conf", config_flags)) && valid_config(cfg)) { 01594 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01595 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01596 ast_debug(4, "users.conf: %s\n", category); 01597 if (!strcasecmp(category, vmu->mailbox)) { 01598 if (!ast_variable_retrieve(cfg, category, "vmsecret")) { 01599 ast_debug(3, "looks like we need to make vmsecret!\n"); 01600 var = ast_variable_new("vmsecret", newpassword, ""); 01601 } else { 01602 var = NULL; 01603 } 01604 new = ast_alloca(strlen(newpassword) + 1); 01605 sprintf(new, "%s", newpassword); 01606 if (!(cat = ast_category_get(cfg, category))) { 01607 ast_debug(4, "failed to get category!\n"); 01608 ast_free(var); 01609 break; 01610 } 01611 if (!var) { 01612 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01613 } else { 01614 ast_variable_append(cat, var); 01615 } 01616 found = 1; 01617 break; 01618 } 01619 } 01620 /* save the results and clean things up */ 01621 if (found) { 01622 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf"); 01623 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01624 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01625 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01626 } 01627 01628 ast_config_destroy(cfg); 01629 } 01630 } 01631 }
| static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
| char * | newpassword | |||
| ) | [static] |
Definition at line 1633 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().
01634 { 01635 char buf[255]; 01636 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01637 ast_debug(1, "External password: %s\n",buf); 01638 if (!ast_safe_system(buf)) { 01639 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external"); 01640 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01641 /* Reset the password in memory, too */ 01642 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01643 } 01644 }
| static char* vm_check_password_shell | ( | char * | command, | |
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 1188 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().
01189 { 01190 int fds[2], pid = 0; 01191 01192 memset(buf, 0, len); 01193 01194 if (pipe(fds)) { 01195 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 01196 } else { 01197 /* good to go*/ 01198 pid = ast_safe_fork(0); 01199 01200 if (pid < 0) { 01201 /* ok maybe not */ 01202 close(fds[0]); 01203 close(fds[1]); 01204 snprintf(buf, len, "FAILURE: Fork failed"); 01205 } else if (pid) { 01206 /* parent */ 01207 close(fds[1]); 01208 if (read(fds[0], buf, len) < 0) { 01209 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 01210 } 01211 close(fds[0]); 01212 } else { 01213 /* child */ 01214 AST_DECLARE_APP_ARGS(arg, 01215 AST_APP_ARG(v)[20]; 01216 ); 01217 char *mycmd = ast_strdupa(command); 01218 01219 close(fds[0]); 01220 dup2(fds[1], STDOUT_FILENO); 01221 close(fds[1]); 01222 ast_close_fds_above_n(STDOUT_FILENO); 01223 01224 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 01225 01226 execv(arg.v[0], arg.v); 01227 printf("FAILURE: %s", strerror(errno)); 01228 _exit(0); 01229 } 01230 } 01231 return buf; 01232 }
| 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 4216 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().
04217 { 04218 char *txt; 04219 int txtsize = 0; 04220 04221 txtsize = (strlen(file) + 5)*sizeof(char); 04222 txt = ast_alloca(txtsize); 04223 /* Sprintf here would safe because we alloca'd exactly the right length, 04224 * but trying to eliminate all sprintf's anyhow 04225 */ 04226 if (ast_check_realtime("voicemail_data")) { 04227 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04228 } 04229 snprintf(txt, txtsize, "%s.txt", file); 04230 unlink(txt); 04231 return ast_filedelete(file, NULL); 04232 }
| static int vm_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 10689 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().
10690 { 10691 int res = 0; 10692 char *tmp; 10693 struct leave_vm_options leave_options; 10694 struct ast_flags flags = { 0 }; 10695 char *opts[OPT_ARG_ARRAY_SIZE]; 10696 AST_DECLARE_APP_ARGS(args, 10697 AST_APP_ARG(argv0); 10698 AST_APP_ARG(argv1); 10699 ); 10700 10701 memset(&leave_options, 0, sizeof(leave_options)); 10702 10703 if (chan->_state != AST_STATE_UP) 10704 ast_answer(chan); 10705 10706 if (!ast_strlen_zero(data)) { 10707 tmp = ast_strdupa(data); 10708 AST_STANDARD_APP_ARGS(args, tmp); 10709 if (args.argc == 2) { 10710 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10711 return -1; 10712 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10713 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10714 int gain; 10715 10716 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10717 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10718 return -1; 10719 } else { 10720 leave_options.record_gain = (signed char) gain; 10721 } 10722 } 10723 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10724 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10725 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10726 } 10727 } 10728 } else { 10729 char temp[256]; 10730 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10731 if (res < 0) 10732 return res; 10733 if (ast_strlen_zero(temp)) 10734 return 0; 10735 args.argv0 = ast_strdupa(temp); 10736 } 10737 10738 res = leave_voicemail(chan, args.argv0, &leave_options); 10739 if (res == 't') { 10740 ast_play_and_wait(chan, "vm-goodbye"); 10741 res = 0; 10742 } 10743 10744 if (res == OPERATOR_EXIT) { 10745 res = 0; 10746 } 10747 10748 if (res == ERROR_LOCK_PATH) { 10749 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10750 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10751 res = 0; 10752 } 10753 10754 return res; 10755 }
| static int vm_execmain | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 9937 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().
09938 { 09939 /* XXX This is, admittedly, some pretty horrendous code. For some 09940 reason it just seemed a lot easier to do with GOTO's. I feel 09941 like I'm back in my GWBASIC days. XXX */ 09942 int res = -1; 09943 int cmd = 0; 09944 int valid = 0; 09945 char prefixstr[80] =""; 09946 char ext_context[256]=""; 09947 int box; 09948 int useadsi = 0; 09949 int skipuser = 0; 09950 struct vm_state vms; 09951 struct ast_vm_user *vmu = NULL, vmus; 09952 char *context = NULL; 09953 int silentexit = 0; 09954 struct ast_flags flags = { 0 }; 09955 signed char record_gain = 0; 09956 int play_auto = 0; 09957 int play_folder = 0; 09958 int in_urgent = 0; 09959 #ifdef IMAP_STORAGE 09960 int deleted = 0; 09961 #endif 09962 09963 /* Add the vm_state to the active list and keep it active */ 09964 memset(&vms, 0, sizeof(vms)); 09965 09966 vms.lastmsg = -1; 09967 09968 memset(&vmus, 0, sizeof(vmus)); 09969 09970 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09971 if (chan->_state != AST_STATE_UP) { 09972 ast_debug(1, "Before ast_answer\n"); 09973 ast_answer(chan); 09974 } 09975 09976 if (!ast_strlen_zero(data)) { 09977 char *opts[OPT_ARG_ARRAY_SIZE]; 09978 char *parse; 09979 AST_DECLARE_APP_ARGS(args, 09980 AST_APP_ARG(argv0); 09981 AST_APP_ARG(argv1); 09982 ); 09983 09984 parse = ast_strdupa(data); 09985 09986 AST_STANDARD_APP_ARGS(args, parse); 09987 09988 if (args.argc == 2) { 09989 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09990 return -1; 09991 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09992 int gain; 09993 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09994 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09995 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09996 return -1; 09997 } else { 09998 record_gain = (signed char) gain; 09999 } 10000 } else { 10001 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 10002 } 10003 } 10004 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 10005 play_auto = 1; 10006 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 10007 /* See if it is a folder name first */ 10008 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 10009 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 10010 play_folder = -1; 10011 } 10012 } else { 10013 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 10014 } 10015 } else { 10016 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 10017 } 10018 if (play_folder > 9 || play_folder < 0) { 10019 ast_log(AST_LOG_WARNING, 10020 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 10021 opts[OPT_ARG_PLAYFOLDER]); 10022 play_folder = 0; 10023 } 10024 } 10025 } else { 10026 /* old style options parsing */ 10027 while (*(args.argv0)) { 10028 if (*(args.argv0) == 's') 10029 ast_set_flag(&flags, OPT_SILENT); 10030 else if (*(args.argv0) == 'p') 10031 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 10032 else 10033 break; 10034 (args.argv0)++; 10035 } 10036 10037 } 10038 10039 valid = ast_test_flag(&flags, OPT_SILENT); 10040 10041 if ((context = strchr(args.argv0, '@'))) 10042 *context++ = '\0'; 10043 10044 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 10045 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 10046 else 10047 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 10048 10049 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 10050 skipuser++; 10051 else 10052 valid = 0; 10053 } 10054 10055 if (!valid) 10056 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 10057 10058 ast_debug(1, "After vm_authenticate\n"); 10059 10060 if (vms.username[0] == '*') { 10061 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 10062 10063 /* user entered '*' */ 10064 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10065 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 10066 res = 0; /* prevent hangup */ 10067 goto out; 10068 } 10069 } 10070 10071 if (!res) { 10072 valid = 1; 10073 if (!skipuser) 10074 vmu = &vmus; 10075 } else { 10076 res = 0; 10077 } 10078 10079 /* If ADSI is supported, setup login screen */ 10080 adsi_begin(chan, &useadsi); 10081 10082 ast_test_suite_assert(valid); 10083 if (!valid) { 10084 goto out; 10085 } 10086 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10087 10088 #ifdef IMAP_STORAGE 10089 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10090 pthread_setspecific(ts_vmstate.key, &vms); 10091 10092 vms.interactive = 1; 10093 vms.updated = 1; 10094 if (vmu) 10095 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10096 vmstate_insert(&vms); 10097 init_vm_state(&vms); 10098 #endif 10099 10100 /* Set language from config to override channel language */ 10101 if (!ast_strlen_zero(vmu->language)) 10102 ast_string_field_set(chan, language, vmu->language); 10103 10104 /* Retrieve urgent, old and new message counts */ 10105 ast_debug(1, "Before open_mailbox\n"); 10106 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10107 if (res < 0) 10108 goto out; 10109 vms.oldmessages = vms.lastmsg + 1; 10110 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10111 /* check INBOX */ 10112 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10113 if (res < 0) 10114 goto out; 10115 vms.newmessages = vms.lastmsg + 1; 10116 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10117 /* Start in Urgent */ 10118 in_urgent = 1; 10119 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10120 if (res < 0) 10121 goto out; 10122 vms.urgentmessages = vms.lastmsg + 1; 10123 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10124 10125 /* Select proper mailbox FIRST!! */ 10126 if (play_auto) { 10127 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10128 if (vms.urgentmessages) { 10129 in_urgent = 1; 10130 res = open_mailbox(&vms, vmu, 11); 10131 } else { 10132 in_urgent = 0; 10133 res = open_mailbox(&vms, vmu, play_folder); 10134 } 10135 if (res < 0) 10136 goto out; 10137 10138 /* If there are no new messages, inform the user and hangup */ 10139 if (vms.lastmsg == -1) { 10140 in_urgent = 0; 10141 cmd = vm_browse_messages(chan, &vms, vmu); 10142 res = 0; 10143 goto out; 10144 } 10145 } else { 10146 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10147 /* If we only have old messages start here */ 10148 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10149 in_urgent = 0; 10150 play_folder = 1; 10151 if (res < 0) 10152 goto out; 10153 } else if (!vms.urgentmessages && vms.newmessages) { 10154 /* If we have new messages but none are urgent */ 10155 in_urgent = 0; 10156 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10157 if (res < 0) 10158 goto out; 10159 } 10160 } 10161 10162 if (useadsi) 10163 adsi_status(chan, &vms); 10164 res = 0; 10165 10166 /* Check to see if this is a new user */ 10167 if (!strcasecmp(vmu->mailbox, vmu->password) && 10168 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10169 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10170 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10171 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10172 if ((cmd == 't') || (cmd == '#')) { 10173 /* Timeout */ 10174 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10175 res = 0; 10176 goto out; 10177 } else if (cmd < 0) { 10178 /* Hangup */ 10179 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10180 res = -1; 10181 goto out; 10182 } 10183 } 10184 #ifdef IMAP_STORAGE 10185 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10186 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10187 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10188 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10189 } 10190 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10191 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10192 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10193 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10194 } 10195 #endif 10196 10197 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10198 if (play_auto) { 10199 cmd = '1'; 10200 } else { 10201 cmd = vm_intro(chan, vmu, &vms); 10202 } 10203 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10204 10205 vms.repeats = 0; 10206 vms.starting = 1; 10207 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10208 /* Run main menu */ 10209 switch (cmd) { 10210 case '1': /* First message */ 10211 vms.curmsg = 0; 10212 /* Fall through */ 10213 case '5': /* Play current message */ 10214 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10215 cmd = vm_browse_messages(chan, &vms, vmu); 10216 break; 10217 case '2': /* Change folders */ 10218 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10219 if (useadsi) 10220 adsi_folders(chan, 0, "Change to folder..."); 10221 10222 cmd = get_folder2(chan, "vm-changeto", 0); 10223 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10224 if (cmd == '#') { 10225 cmd = 0; 10226 } else if (cmd > 0) { 10227 cmd = cmd - '0'; 10228 res = close_mailbox(&vms, vmu); 10229 if (res == ERROR_LOCK_PATH) 10230 goto out; 10231 /* If folder is not urgent, set in_urgent to zero! */ 10232 if (cmd != 11) in_urgent = 0; 10233 res = open_mailbox(&vms, vmu, cmd); 10234 if (res < 0) 10235 goto out; 10236 play_folder = cmd; 10237 cmd = 0; 10238 } 10239 if (useadsi) 10240 adsi_status2(chan, &vms); 10241 10242 if (!cmd) { 10243 cmd = vm_play_folder_name(chan, vms.vmbox); 10244 } 10245 10246 vms.starting = 1; 10247 vms.curmsg = 0; 10248 break; 10249 case '3': /* Advanced options */ 10250 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10251 cmd = 0; 10252 vms.repeats = 0; 10253 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10254 switch (cmd) { 10255 case '1': /* Reply */ 10256 if (vms.lastmsg > -1 && !vms.starting) { 10257 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10258 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10259 res = cmd; 10260 goto out; 10261 } 10262 } else { 10263 cmd = ast_play_and_wait(chan, "vm-sorry"); 10264 } 10265 cmd = 't'; 10266 break; 10267 case '2': /* Callback */ 10268 if (!vms.starting) 10269 ast_verb(3, "Callback Requested\n"); 10270 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10271 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10272 if (cmd == 9) { 10273 silentexit = 1; 10274 goto out; 10275 } else if (cmd == ERROR_LOCK_PATH) { 10276 res = cmd; 10277 goto out; 10278 } 10279 } else { 10280 cmd = ast_play_and_wait(chan, "vm-sorry"); 10281 } 10282 cmd = 't'; 10283 break; 10284 case '3': /* Envelope */ 10285 if (vms.lastmsg > -1 && !vms.starting) { 10286 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10287 if (cmd == ERROR_LOCK_PATH) { 10288 res = cmd; 10289 goto out; 10290 } 10291 } else { 10292 cmd = ast_play_and_wait(chan, "vm-sorry"); 10293 } 10294 cmd = 't'; 10295 break; 10296 case '4': /* Dialout */ 10297 if (!ast_strlen_zero(vmu->dialout)) { 10298 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10299 if (cmd == 9) { 10300 silentexit = 1; 10301 goto out; 10302 } 10303 } else { 10304 cmd = ast_play_and_wait(chan, "vm-sorry"); 10305 } 10306 cmd = 't'; 10307 break; 10308 10309 case '5': /* Leave VoiceMail */ 10310 if (ast_test_flag(vmu, VM_SVMAIL)) { 10311 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10312 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10313 res = cmd; 10314 goto out; 10315 } 10316 } else { 10317 cmd = ast_play_and_wait(chan, "vm-sorry"); 10318 } 10319 cmd = 't'; 10320 break; 10321 10322 case '*': /* Return to main menu */ 10323 cmd = 't'; 10324 break; 10325 10326 default: 10327 cmd = 0; 10328 if (!vms.starting) { 10329 cmd = ast_play_and_wait(chan, "vm-toreply"); 10330 } 10331 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10332 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10333 } 10334 if (!cmd && !vms.starting) { 10335 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10336 } 10337 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10338 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10339 } 10340 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10341 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10342 } 10343 if (!cmd) { 10344 cmd = ast_play_and_wait(chan, "vm-starmain"); 10345 } 10346 if (!cmd) { 10347 cmd = ast_waitfordigit(chan, 6000); 10348 } 10349 if (!cmd) { 10350 vms.repeats++; 10351 } 10352 if (vms.repeats > 3) { 10353 cmd = 't'; 10354 } 10355 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10356 } 10357 } 10358 if (cmd == 't') { 10359 cmd = 0; 10360 vms.repeats = 0; 10361 } 10362 break; 10363 case '4': /* Go to the previous message */ 10364 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10365 if (vms.curmsg > 0) { 10366 vms.curmsg--; 10367 cmd = play_message(chan, vmu, &vms); 10368 } else { 10369 /* Check if we were listening to new 10370 messages. If so, go to Urgent messages 10371 instead of saying "no more messages" 10372 */ 10373 if (in_urgent == 0 && vms.urgentmessages > 0) { 10374 /* Check for Urgent messages */ 10375 in_urgent = 1; 10376 res = close_mailbox(&vms, vmu); 10377 if (res == ERROR_LOCK_PATH) 10378 goto out; 10379 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10380 if (res < 0) 10381 goto out; 10382 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10383 vms.curmsg = vms.lastmsg; 10384 if (vms.lastmsg < 0) { 10385 cmd = ast_play_and_wait(chan, "vm-nomore"); 10386 } 10387 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10388 vms.curmsg = vms.lastmsg; 10389 cmd = play_message(chan, vmu, &vms); 10390 } else { 10391 cmd = ast_play_and_wait(chan, "vm-nomore"); 10392 } 10393 } 10394 break; 10395 case '6': /* Go to the next message */ 10396 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10397 if (vms.curmsg < vms.lastmsg) { 10398 vms.curmsg++; 10399 cmd = play_message(chan, vmu, &vms); 10400 } else { 10401 if (in_urgent && vms.newmessages > 0) { 10402 /* Check if we were listening to urgent 10403 * messages. If so, go to regular new messages 10404 * instead of saying "no more messages" 10405 */ 10406 in_urgent = 0; 10407 res = close_mailbox(&vms, vmu); 10408 if (res == ERROR_LOCK_PATH) 10409 goto out; 10410 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10411 if (res < 0) 10412 goto out; 10413 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10414 vms.curmsg = -1; 10415 if (vms.lastmsg < 0) { 10416 cmd = ast_play_and_wait(chan, "vm-nomore"); 10417 } 10418 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10419 vms.curmsg = 0; 10420 cmd = play_message(chan, vmu, &vms); 10421 } else { 10422 cmd = ast_play_and_wait(chan, "vm-nomore"); 10423 } 10424 } 10425 break; 10426 case '7': /* Delete the current message */ 10427 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10428 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10429 if (useadsi) 10430 adsi_delete(chan, &vms); 10431 if (vms.deleted[vms.curmsg]) { 10432 if (play_folder == 0) { 10433 if (in_urgent) { 10434 vms.urgentmessages--; 10435 } else { 10436 vms.newmessages--; 10437 } 10438 } 10439 else if (play_folder == 1) 10440 vms.oldmessages--; 10441 cmd = ast_play_and_wait(chan, "vm-deleted"); 10442 } else { 10443 if (play_folder == 0) { 10444 if (in_urgent) { 10445 vms.urgentmessages++; 10446 } else { 10447 vms.newmessages++; 10448 } 10449 } 10450 else if (play_folder == 1) 10451 vms.oldmessages++; 10452 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10453 } 10454 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10455 if (vms.curmsg < vms.lastmsg) { 10456 vms.curmsg++; 10457 cmd = play_message(chan, vmu, &vms); 10458 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10459 vms.curmsg = 0; 10460 cmd = play_message(chan, vmu, &vms); 10461 } else { 10462 /* Check if we were listening to urgent 10463 messages. If so, go to regular new messages 10464 instead of saying "no more messages" 10465 */ 10466 if (in_urgent == 1) { 10467 /* Check for new messages */ 10468 in_urgent = 0; 10469 res = close_mailbox(&vms, vmu); 10470 if (res == ERROR_LOCK_PATH) 10471 goto out; 10472 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10473 if (res < 0) 10474 goto out; 10475 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10476 vms.curmsg = -1; 10477 if (vms.lastmsg < 0) { 10478 cmd = ast_play_and_wait(chan, "vm-nomore"); 10479 } 10480 } else { 10481 cmd = ast_play_and_wait(chan, "vm-nomore"); 10482 } 10483 } 10484 } 10485 } else /* Delete not valid if we haven't selected a message */ 10486 cmd = 0; 10487 #ifdef IMAP_STORAGE 10488 deleted = 1; 10489 #endif 10490 break; 10491 10492 case '8': /* Forward the current message */ 10493 if (vms.lastmsg > -1) { 10494 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10495 if (cmd == ERROR_LOCK_PATH) { 10496 res = cmd; 10497 goto out; 10498 } 10499 } else { 10500 /* Check if we were listening to urgent 10501 messages. If so, go to regular new messages 10502 instead of saying "no more messages" 10503 */ 10504 if (in_urgent == 1 && vms.newmessages > 0) { 10505 /* Check for new messages */ 10506 in_urgent = 0; 10507 res = close_mailbox(&vms, vmu); 10508 if (res == ERROR_LOCK_PATH) 10509 goto out; 10510 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10511 if (res < 0) 10512 goto out; 10513 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10514 vms.curmsg = -1; 10515 if (vms.lastmsg < 0) { 10516 cmd = ast_play_and_wait(chan, "vm-nomore"); 10517 } 10518 } else { 10519 cmd = ast_play_and_wait(chan, "vm-nomore"); 10520 } 10521 } 10522 break; 10523 case '9': /* Save message to folder */ 10524 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10525 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10526 /* No message selected */ 10527 cmd = 0; 10528 break; 10529 } 10530 if (useadsi) 10531 adsi_folders(chan, 1, "Save to folder..."); 10532 cmd = get_folder2(chan, "vm-savefolder", 1); 10533 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10534 box = 0; /* Shut up compiler */ 10535 if (cmd == '#') { 10536 cmd = 0; 10537 break; 10538 } else if (cmd > 0) { 10539 box = cmd = cmd - '0'; 10540 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10541 if (cmd == ERROR_LOCK_PATH) { 10542 res = cmd; 10543 goto out; 10544 #ifndef IMAP_STORAGE 10545 } else if (!cmd) { 10546 vms.deleted[vms.curmsg] = 1; 10547 #endif 10548 } else { 10549 vms.deleted[vms.curmsg] = 0; 10550 vms.heard[vms.curmsg] = 0; 10551 } 10552 } 10553 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10554 if (useadsi) 10555 adsi_message(chan, &vms); 10556 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10557 if (!cmd) { 10558 cmd = ast_play_and_wait(chan, "vm-message"); 10559 if (!cmd) 10560 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10561 if (!cmd) 10562 cmd = ast_play_and_wait(chan, "vm-savedto"); 10563 if (!cmd) 10564 cmd = vm_play_folder_name(chan, vms.fn); 10565 } else { 10566 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10567 } 10568 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10569 if (vms.curmsg < vms.lastmsg) { 10570 vms.curmsg++; 10571 cmd = play_message(chan, vmu, &vms); 10572 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10573 vms.curmsg = 0; 10574 cmd = play_message(chan, vmu, &vms); 10575 } else { 10576 /* Check if we were listening to urgent 10577 messages. If so, go to regular new messages 10578 instead of saying "no more messages" 10579 */ 10580 if (in_urgent == 1 && vms.newmessages > 0) { 10581 /* Check for new messages */ 10582 in_urgent = 0; 10583 res = close_mailbox(&vms, vmu); 10584 if (res == ERROR_LOCK_PATH) 10585 goto out; 10586 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10587 if (res < 0) 10588 goto out; 10589 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10590 vms.curmsg = -1; 10591 if (vms.lastmsg < 0) { 10592 cmd = ast_play_and_wait(chan, "vm-nomore"); 10593 } 10594 } else { 10595 cmd = ast_play_and_wait(chan, "vm-nomore"); 10596 } 10597 } 10598 } 10599 break; 10600 case '*': /* Help */ 10601 if (!vms.starting) { 10602 cmd = ast_play_and_wait(chan, "vm-onefor"); 10603 if (!strncasecmp(chan->language, "he", 2)) { 10604 cmd = ast_play_and_wait(chan, "vm-for"); 10605 } 10606 if (!cmd) 10607 cmd = vm_play_folder_name(chan, vms.vmbox); 10608 if (!cmd) 10609 cmd = ast_play_and_wait(chan, "vm-opts"); 10610 if (!cmd) 10611 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10612 } else 10613 cmd = 0; 10614 break; 10615 case '0': /* Mailbox options */ 10616 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10617 if (useadsi) 10618 adsi_status(chan, &vms); 10619 break; 10620 default: /* Nothing */ 10621 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10622 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10623 break; 10624 } 10625 } 10626 if ((cmd == 't') || (cmd == '#')) { 10627 /* Timeout */ 10628 res = 0; 10629 } else { 10630 /* Hangup */ 10631 res = -1; 10632 } 10633 10634 out: 10635 if (res > -1) { 10636 ast_stopstream(chan); 10637 adsi_goodbye(chan); 10638 if (valid && res != OPERATOR_EXIT) { 10639 if (silentexit) 10640 res = ast_play_and_wait(chan, "vm-dialout"); 10641 else 10642 res = ast_play_and_wait(chan, "vm-goodbye"); 10643 } 10644 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10645 res = 0; 10646 } 10647 if (useadsi) 10648 ast_adsi_unload_session(chan); 10649 } 10650 if (vmu) 10651 close_mailbox(&vms, vmu); 10652 if (valid) { 10653 int new = 0, old = 0, urgent = 0; 10654 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10655 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10656 /* Urgent flag not passwd to externnotify here */ 10657 run_externnotify(vmu->context, vmu->mailbox, NULL); 10658 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10659 queue_mwi_event(ext_context, urgent, new, old); 10660 } 10661 #ifdef IMAP_STORAGE 10662 /* expunge message - use UID Expunge if supported on IMAP server*/ 10663 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10664 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10665 ast_mutex_lock(&vms.lock); 10666 #ifdef HAVE_IMAP_TK2006 10667 if (LEVELUIDPLUS (vms.mailstream)) { 10668 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10669 } else 10670 #endif 10671 mail_expunge(vms.mailstream); 10672 ast_mutex_unlock(&vms.lock); 10673 } 10674 /* before we delete the state, we should copy pertinent info 10675 * back to the persistent model */ 10676 if (vmu) { 10677 vmstate_delete(&vms); 10678 } 10679 #endif 10680 if (vmu) 10681 free_user(vmu); 10682 10683 #ifdef IMAP_STORAGE 10684 pthread_setspecific(ts_vmstate.key, NULL); 10685 #endif 10686 return res; 10687 }
| 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 6897 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().
06899 { 06900 int cmd = 0; 06901 int retries = 0, prepend_duration = 0, already_recorded = 0; 06902 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06903 char textfile[PATH_MAX]; 06904 struct ast_config *msg_cfg; 06905 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06906 #ifndef IMAP_STORAGE 06907 signed char zero_gain = 0; 06908 #endif 06909 const char *duration_str; 06910 06911 /* Must always populate duration correctly */ 06912 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06913 strcpy(textfile, msgfile); 06914 strcpy(backup, msgfile); 06915 strcpy(backup_textfile, msgfile); 06916 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06917 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06918 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06919 06920 if ((msg_cfg = ast_config_load(textfile, config_flags)) && valid_config(msg_cfg) && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06921 *duration = atoi(duration_str); 06922 } else { 06923 *duration = 0; 06924 } 06925 06926 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06927 if (cmd) 06928 retries = 0; 06929 switch (cmd) { 06930 case '1': 06931 06932 #ifdef IMAP_STORAGE 06933 /* Record new intro file */ 06934 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06935 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06936 ast_play_and_wait(chan, INTRO); 06937 ast_play_and_wait(chan, "beep"); 06938 cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06939 if (cmd == -1) { 06940 break; 06941 } 06942 cmd = 't'; 06943 #else 06944 06945 /* prepend a message to the current message, update the metadata and return */ 06946 06947 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06948 strcpy(textfile, msgfile); 06949 strncat(textfile, ".txt", sizeof(textfile) - 1); 06950 *duration = 0; 06951 06952 /* if we can't read the message metadata, stop now */ 06953 if (!valid_config(msg_cfg)) { 06954 cmd = 0; 06955 break; 06956 } 06957 06958 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06959 #ifndef IMAP_STORAGE 06960 if (already_recorded) { 06961 ast_filecopy(backup, msgfile, NULL); 06962 copy(backup_textfile, textfile); 06963 } 06964 else { 06965 ast_filecopy(msgfile, backup, NULL); 06966 copy(textfile, backup_textfile); 06967 } 06968 #endif 06969 already_recorded = 1; 06970 06971 if (record_gain) 06972 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06973 06974 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 06975 06976 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 06977 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 06978 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 06979 ast_filerename(backup, msgfile, NULL); 06980 } 06981 06982 if (record_gain) 06983 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06984 06985 06986 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06987 *duration = atoi(duration_str); 06988 06989 if (prepend_duration) { 06990 struct ast_category *msg_cat; 06991 /* need enough space for a maximum-length message duration */ 06992 char duration_buf[12]; 06993 06994 *duration += prepend_duration; 06995 msg_cat = ast_category_get(msg_cfg, "message"); 06996 snprintf(duration_buf, 11, "%ld", *duration); 06997 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06998 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06999 } 07000 } 07001 07002 #endif 07003 break; 07004 case '2': 07005 /* NULL out introfile so we know there is no intro! */ 07006 #ifdef IMAP_STORAGE 07007 *vms->introfn = '\0'; 07008 #endif 07009 cmd = 't'; 07010 break; 07011 case '*': 07012 cmd = '*'; 07013 break; 07014 default: 07015 /* If time_out and return to menu, reset already_recorded */ 07016 already_recorded = 0; 07017 07018 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 07019 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 07020 if (!cmd) { 07021 cmd = ast_play_and_wait(chan, "vm-starmain"); 07022 /* "press star to return to the main menu" */ 07023 } 07024 if (!cmd) { 07025 cmd = ast_waitfordigit(chan, 6000); 07026 } 07027 if (!cmd) { 07028 retries++; 07029 } 07030 if (retries > 3) { 07031 cmd = '*'; /* Let's cancel this beast */ 07032 } 07033 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07034 } 07035 } 07036 07037 if (valid_config(msg_cfg)) 07038 ast_config_destroy(msg_cfg); 07039 if (prepend_duration) 07040 *duration = prepend_duration; 07041 07042 if (already_recorded && cmd == -1) { 07043 /* restore original message if prepention cancelled */ 07044 ast_filerename(backup, msgfile, NULL); 07045 rename(backup_textfile, textfile); 07046 } 07047 07048 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 07049 cmd = 0; 07050 return cmd; 07051 }
| 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 9252 of file app_voicemail.c.
References vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
09253 { 09254 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09255 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09256 } else { /* Default to ENGLISH */ 09257 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09258 } 09259 }
| 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 9140 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().
09141 { 09142 int res = 0; 09143 /* Play instructions and wait for new command */ 09144 while (!res) { 09145 if (vms->starting) { 09146 if (vms->lastmsg > -1) { 09147 if (skipadvanced) 09148 res = ast_play_and_wait(chan, "vm-onefor-full"); 09149 else 09150 res = ast_play_and_wait(chan, "vm-onefor"); 09151 if (!res) 09152 res = vm_play_folder_name(chan, vms->vmbox); 09153 } 09154 if (!res) { 09155 if (skipadvanced) 09156 res = ast_play_and_wait(chan, "vm-opts-full"); 09157 else 09158 res = ast_play_and_wait(chan, "vm-opts"); 09159 } 09160 } else { 09161 /* Added for additional help */ 09162 if (skipadvanced) { 09163 res = ast_play_and_wait(chan, "vm-onefor-full"); 09164 if (!res) 09165 res = vm_play_folder_name(chan, vms->vmbox); 09166 res = ast_play_and_wait(chan, "vm-opts-full"); 09167 } 09168 /* Logic: 09169 * If the current message is not the first OR 09170 * if we're listening to the first new message and there are 09171 * also urgent messages, then prompt for navigation to the 09172 * previous message 09173 */ 09174 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09175 res = ast_play_and_wait(chan, "vm-prev"); 09176 } 09177 if (!res && !skipadvanced) 09178 res = ast_play_and_wait(chan, "vm-advopts"); 09179 if (!res) 09180 res = ast_play_and_wait(chan, "vm-repeat"); 09181 /* Logic: 09182 * If we're not listening to the last message OR 09183 * we're listening to the last urgent message and there are 09184 * also new non-urgent messages, then prompt for navigation 09185 * to the next message 09186 */ 09187 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09188 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09189 res = ast_play_and_wait(chan, "vm-next"); 09190 } 09191 if (!res) { 09192 int curmsg_deleted; 09193 #ifdef IMAP_STORAGE 09194 ast_mutex_lock(&vms->lock); 09195 #endif 09196 curmsg_deleted = vms->deleted[vms->curmsg]; 09197 #ifdef IMAP_STORAGE 09198 ast_mutex_unlock(&vms->lock); 09199 #endif 09200 if (!curmsg_deleted) { 09201 res = ast_play_and_wait(chan, "vm-delete"); 09202 } else { 09203 res = ast_play_and_wait(chan, "vm-undelete"); 09204 } 09205 if (!res) { 09206 res = ast_play_and_wait(chan, "vm-toforward"); 09207 } 09208 if (!res) { 09209 res = ast_play_and_wait(chan, "vm-savemessage"); 09210 } 09211 } 09212 } 09213 if (!res) { 09214 res = ast_play_and_wait(chan, "vm-helpexit"); 09215 } 09216 if (!res) 09217 res = ast_waitfordigit(chan, 6000); 09218 if (!res) { 09219 vms->repeats++; 09220 if (vms->repeats > 2) { 09221 res = 't'; 09222 } 09223 } 09224 } 09225 return res; 09226 }
| 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 9228 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().
09229 { 09230 int res = 0; 09231 /* Play instructions and wait for new command */ 09232 while (!res) { 09233 if (vms->lastmsg > -1) { 09234 res = ast_play_and_wait(chan, "vm-listen"); 09235 if (!res) 09236 res = vm_play_folder_name(chan, vms->vmbox); 09237 if (!res) 09238 res = ast_play_and_wait(chan, "press"); 09239 if (!res) 09240 res = ast_play_and_wait(chan, "digits/1"); 09241 } 09242 if (!res) 09243 res = ast_play_and_wait(chan, "vm-opts"); 09244 if (!res) { 09245 vms->starting = 0; 09246 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09247 } 09248 } 09249 return res; 09250 }
| static int vm_intro | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 9078 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().
09079 { 09080 char prefile[256]; 09081 09082 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09083 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09084 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09085 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09086 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09087 ast_play_and_wait(chan, "vm-tempgreetactive"); 09088 } 09089 DISPOSE(prefile, -1); 09090 } 09091 09092 /* Play voicemail intro - syntax is different for different languages */ 09093 if (0) { 09094 return 0; 09095 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09096 return vm_intro_cs(chan, vms); 09097 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09098 static int deprecation_warning = 0; 09099 if (deprecation_warning++ % 10 == 0) { 09100 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09101 } 09102 return vm_intro_cs(chan, vms); 09103 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09104 return vm_intro_de(chan, vms); 09105 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09106 return vm_intro_es(chan, vms); 09107 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09108 return vm_intro_fr(chan, vms); 09109 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09110 return vm_intro_gr(chan, vms); 09111 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09112 return vm_intro_he(chan, vms); 09113 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09114 return vm_intro_it(chan, vms); 09115 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09116 return vm_intro_nl(chan, vms); 09117 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09118 return vm_intro_no(chan, vms); 09119 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09120 return vm_intro_pl(chan, vms); 09121 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09122 return vm_intro_pt_BR(chan, vms); 09123 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09124 return vm_intro_pt(chan, vms); 09125 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09126 return vm_intro_multilang(chan, vms, "n"); 09127 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09128 return vm_intro_se(chan, vms); 09129 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09130 return vm_intro_multilang(chan, vms, "n"); 09131 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09132 return vm_intro_vi(chan, vms); 09133 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09134 return vm_intro_zh(chan, vms); 09135 } else { /* Default to ENGLISH */ 09136 return vm_intro_en(chan, vms); 09137 } 09138 }
| static int vm_intro_cs | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8948 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().
08949 { 08950 int res; 08951 res = ast_play_and_wait(chan, "vm-youhave"); 08952 if (!res) { 08953 if (vms->newmessages) { 08954 if (vms->newmessages == 1) { 08955 res = ast_play_and_wait(chan, "digits/jednu"); 08956 } else { 08957 res = say_and_wait(chan, vms->newmessages, chan->language); 08958 } 08959 if (!res) { 08960 if ((vms->newmessages == 1)) 08961 res = ast_play_and_wait(chan, "vm-novou"); 08962 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08963 res = ast_play_and_wait(chan, "vm-nove"); 08964 if (vms->newmessages > 4) 08965 res = ast_play_and_wait(chan, "vm-novych"); 08966 } 08967 if (vms->oldmessages && !res) 08968 res = ast_play_and_wait(chan, "vm-and"); 08969 else if (!res) { 08970 if ((vms->newmessages == 1)) 08971 res = ast_play_and_wait(chan, "vm-zpravu"); 08972 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08973 res = ast_play_and_wait(chan, "vm-zpravy"); 08974 if (vms->newmessages > 4) 08975 res = ast_play_and_wait(chan, "vm-zprav"); 08976 } 08977 } 08978 if (!res && vms->oldmessages) { 08979 res = say_and_wait(chan, vms->oldmessages, chan->language); 08980 if (!res) { 08981 if ((vms->oldmessages == 1)) 08982 res = ast_play_and_wait(chan, "vm-starou"); 08983 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08984 res = ast_play_and_wait(chan, "vm-stare"); 08985 if (vms->oldmessages > 4) 08986 res = ast_play_and_wait(chan, "vm-starych"); 08987 } 08988 if (!res) { 08989 if ((vms->oldmessages == 1)) 08990 res = ast_play_and_wait(chan, "vm-zpravu"); 08991 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08992 res = ast_play_and_wait(chan, "vm-zpravy"); 08993 if (vms->oldmessages > 4) 08994 res = ast_play_and_wait(chan, "vm-zprav"); 08995 } 08996 } 08997 if (!res) { 08998 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08999 res = ast_play_and_wait(chan, "vm-no"); 09000 if (!res) 09001 res = ast_play_and_wait(chan, "vm-zpravy"); 09002 } 09003 } 09004 } 09005 return res; 09006 }
| static int vm_intro_de | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8644 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().
08645 { 08646 /* Introduce messages they have */ 08647 int res; 08648 res = ast_play_and_wait(chan, "vm-youhave"); 08649 if (!res) { 08650 if (vms->newmessages) { 08651 if ((vms->newmessages == 1)) 08652 res = ast_play_and_wait(chan, "digits/1F"); 08653 else 08654 res = say_and_wait(chan, vms->newmessages, chan->language); 08655 if (!res) 08656 res = ast_play_and_wait(chan, "vm-INBOX"); 08657 if (vms->oldmessages && !res) 08658 res = ast_play_and_wait(chan, "vm-and"); 08659 else if (!res) { 08660 if ((vms->newmessages == 1)) 08661 res = ast_play_and_wait(chan, "vm-message"); 08662 else 08663 res = ast_play_and_wait(chan, "vm-messages"); 08664 } 08665 08666 } 08667 if (!res && vms->oldmessages) { 08668 if (vms->oldmessages == 1) 08669 res = ast_play_and_wait(chan, "digits/1F"); 08670 else 08671 res = say_and_wait(chan, vms->oldmessages, chan->language); 08672 if (!res) 08673 res = ast_play_and_wait(chan, "vm-Old"); 08674 if (!res) { 08675 if (vms->oldmessages == 1) 08676 res = ast_play_and_wait(chan, "vm-message"); 08677 else 08678 res = ast_play_and_wait(chan, "vm-messages"); 08679 } 08680 } 08681 if (!res) { 08682 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08683 res = ast_play_and_wait(chan, "vm-no"); 08684 if (!res) 08685 res = ast_play_and_wait(chan, "vm-messages"); 08686 } 08687 } 08688 } 08689 return res; 08690 }
| static int vm_intro_en | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8393 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().
08394 { 08395 int res; 08396 08397 /* Introduce messages they have */ 08398 res = ast_play_and_wait(chan, "vm-youhave"); 08399 if (!res) { 08400 if (vms->urgentmessages) { 08401 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08402 if (!res) 08403 res = ast_play_and_wait(chan, "vm-Urgent"); 08404 if ((vms->oldmessages || vms->newmessages) && !res) { 08405 res = ast_play_and_wait(chan, "vm-and"); 08406 } else if (!res) { 08407 if ((vms->urgentmessages == 1)) 08408 res = ast_play_and_wait(chan, "vm-message"); 08409 else 08410 res = ast_play_and_wait(chan, "vm-messages"); 08411 } 08412 } 08413 if (vms->newmessages) { 08414 res = say_and_wait(chan, vms->newmessages, chan->language); 08415 if (!res) 08416 res = ast_play_and_wait(chan, "vm-INBOX"); 08417 if (vms->oldmessages && !res) 08418 res = ast_play_and_wait(chan, "vm-and"); 08419 else if (!res) { 08420 if ((vms->newmessages == 1)) 08421 res = ast_play_and_wait(chan, "vm-message"); 08422 else 08423 res = ast_play_and_wait(chan, "vm-messages"); 08424 } 08425 08426 } 08427 if (!res && vms->oldmessages) { 08428 res = say_and_wait(chan, vms->oldmessages, chan->language); 08429 if (!res) 08430 res = ast_play_and_wait(chan, "vm-Old"); 08431 if (!res) { 08432 if (vms->oldmessages == 1) 08433 res = ast_play_and_wait(chan, "vm-message"); 08434 else 08435 res = ast_play_and_wait(chan, "vm-messages"); 08436 } 08437 } 08438 if (!res) { 08439 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08440 res = ast_play_and_wait(chan, "vm-no"); 08441 if (!res) 08442 res = ast_play_and_wait(chan, "vm-messages"); 08443 } 08444 } 08445 } 08446 return res; 08447 }
| static int vm_intro_es | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8693 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().
08694 { 08695 /* Introduce messages they have */ 08696 int res; 08697 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08698 res = ast_play_and_wait(chan, "vm-youhaveno"); 08699 if (!res) 08700 res = ast_play_and_wait(chan, "vm-messages"); 08701 } else { 08702 res = ast_play_and_wait(chan, "vm-youhave"); 08703 } 08704 if (!res) { 08705 if (vms->newmessages) { 08706 if (!res) { 08707 if ((vms->newmessages == 1)) { 08708 res = ast_play_and_wait(chan, "digits/1M"); 08709 if (!res) 08710 res = ast_play_and_wait(chan, "vm-message"); 08711 if (!res) 08712 res = ast_play_and_wait(chan, "vm-INBOXs"); 08713 } else { 08714 res = say_and_wait(chan, vms->newmessages, chan->language); 08715 if (!res) 08716 res = ast_play_and_wait(chan, "vm-messages"); 08717 if (!res) 08718 res = ast_play_and_wait(chan, "vm-INBOX"); 08719 } 08720 } 08721 if (vms->oldmessages && !res) 08722 res = ast_play_and_wait(chan, "vm-and"); 08723 } 08724 if (vms->oldmessages) { 08725 if (!res) { 08726 if (vms->oldmessages == 1) { 08727 res = ast_play_and_wait(chan, "digits/1M"); 08728 if (!res) 08729 res = ast_play_and_wait(chan, "vm-message"); 08730 if (!res) 08731 res = ast_play_and_wait(chan, "vm-Olds"); 08732 } else { 08733 res = say_and_wait(chan, vms->oldmessages, chan->language); 08734 if (!res) 08735 res = ast_play_and_wait(chan, "vm-messages"); 08736 if (!res) 08737 res = ast_play_and_wait(chan, "vm-Old"); 08738 } 08739 } 08740 } 08741 } 08742 return res; 08743 }
| static int vm_intro_fr | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8791 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().
08792 { 08793 /* Introduce messages they have */ 08794 int res; 08795 res = ast_play_and_wait(chan, "vm-youhave"); 08796 if (!res) { 08797 if (vms->newmessages) { 08798 res = say_and_wait(chan, vms->newmessages, chan->language); 08799 if (!res) 08800 res = ast_play_and_wait(chan, "vm-INBOX"); 08801 if (vms->oldmessages && !res) 08802 res = ast_play_and_wait(chan, "vm-and"); 08803 else if (!res) { 08804 if ((vms->newmessages == 1)) 08805 res = ast_play_and_wait(chan, "vm-message"); 08806 else 08807 res = ast_play_and_wait(chan, "vm-messages"); 08808 } 08809 08810 } 08811 if (!res && vms->oldmessages) { 08812 res = say_and_wait(chan, vms->oldmessages, chan->language); 08813 if (!res) 08814 res = ast_play_and_wait(chan, "vm-Old"); 08815 if (!res) { 08816 if (vms->oldmessages == 1) 08817 res = ast_play_and_wait(chan, "vm-message"); 08818 else 08819 res = ast_play_and_wait(chan, "vm-messages"); 08820 } 08821 } 08822 if (!res) { 08823 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08824 res = ast_play_and_wait(chan, "vm-no"); 08825 if (!res) 08826 res = ast_play_and_wait(chan, "vm-messages"); 08827 } 08828 } 08829 } 08830 return res; 08831 }
| static int vm_intro_gr | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8192 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().
08193 { 08194 int res = 0; 08195 08196 if (vms->newmessages) { 08197 res = ast_play_and_wait(chan, "vm-youhave"); 08198 if (!res) 08199 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08200 if (!res) { 08201 if ((vms->newmessages == 1)) { 08202 res = ast_play_and_wait(chan, "vm-INBOX"); 08203 if (!res) 08204 res = ast_play_and_wait(chan, "vm-message"); 08205 } else { 08206 res = ast_play_and_wait(chan, "vm-INBOXs"); 08207 if (!res) 08208 res = ast_play_and_wait(chan, "vm-messages"); 08209 } 08210 } 08211 } else if (vms->oldmessages){ 08212 res = ast_play_and_wait(chan, "vm-youhave"); 08213 if (!res) 08214 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08215 if ((vms->oldmessages == 1)){ 08216 res = ast_play_and_wait(chan, "vm-Old"); 08217 if (!res) 08218 res = ast_play_and_wait(chan, "vm-message"); 08219 } else { 08220 res = ast_play_and_wait(chan, "vm-Olds"); 08221 if (!res) 08222 res = ast_play_and_wait(chan, "vm-messages"); 08223 } 08224 } else if (!vms->oldmessages && !vms->newmessages) 08225 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08226 return res; 08227 }
| static int vm_intro_he | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8326 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().
08327 { 08328 int res = 0; 08329 08330 /* Introduce messages they have */ 08331 if (!res) { 08332 if ((vms->newmessages) || (vms->oldmessages)) { 08333 res = ast_play_and_wait(chan, "vm-youhave"); 08334 } 08335 /* 08336 * The word "shtei" refers to the number 2 in hebrew when performing a count 08337 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08338 * an element, this is one of them. 08339 */ 08340 if (vms->newmessages) { 08341 if (!res) { 08342 if (vms->newmessages == 1) { 08343 res = ast_play_and_wait(chan, "vm-INBOX1"); 08344 } else { 08345 if (vms->newmessages == 2) { 08346 res = ast_play_and_wait(chan, "vm-shtei"); 08347 } else { 08348 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08349 } 08350 res = ast_play_and_wait(chan, "vm-INBOX"); 08351 } 08352 } 08353 if (vms->oldmessages && !res) { 08354 res = ast_play_and_wait(chan, "vm-and"); 08355 if (vms->oldmessages == 1) { 08356 res = ast_play_and_wait(chan, "vm-Old1"); 08357 } else { 08358 if (vms->oldmessages == 2) { 08359 res = ast_play_and_wait(chan, "vm-shtei"); 08360 } else { 08361 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08362 } 08363 res = ast_play_and_wait(chan, "vm-Old"); 08364 } 08365 } 08366 } 08367 if (!res && vms->oldmessages && !vms->newmessages) { 08368 if (!res) { 08369 if (vms->oldmessages == 1) { 08370 res = ast_play_and_wait(chan, "vm-Old1"); 08371 } else { 08372 if (vms->oldmessages == 2) { 08373 res = ast_play_and_wait(chan, "vm-shtei"); 08374 } else { 08375 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08376 } 08377 res = ast_play_and_wait(chan, "vm-Old"); 08378 } 08379 } 08380 } 08381 if (!res) { 08382 if (!vms->oldmessages && !vms->newmessages) { 08383 if (!res) { 08384 res = ast_play_and_wait(chan, "vm-nomessages"); 08385 } 08386 } 08387 } 08388 } 08389 return res; 08390 }
| static int vm_intro_it | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8450 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().
08451 { 08452 /* Introduce messages they have */ 08453 int res; 08454 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08455 res = ast_play_and_wait(chan, "vm-no") || 08456 ast_play_and_wait(chan, "vm-message"); 08457 else 08458 res = ast_play_and_wait(chan, "vm-youhave"); 08459 if (!res && vms->newmessages) { 08460 res = (vms->newmessages == 1) ? 08461 ast_play_and_wait(chan, "digits/un") || 08462 ast_play_and_wait(chan, "vm-nuovo") || 08463 ast_play_and_wait(chan, "vm-message") : 08464 /* 2 or more new messages */ 08465 say_and_wait(chan, vms->newmessages, chan->language) || 08466 ast_play_and_wait(chan, "vm-nuovi") || 08467 ast_play_and_wait(chan, "vm-messages"); 08468 if (!res && vms->oldmessages) 08469 res = ast_play_and_wait(chan, "vm-and"); 08470 } 08471 if (!res && vms->oldmessages) { 08472 res = (vms->oldmessages == 1) ? 08473 ast_play_and_wait(chan, "digits/un") || 08474 ast_play_and_wait(chan, "vm-vecchio") || 08475 ast_play_and_wait(chan, "vm-message") : 08476 /* 2 or more old messages */ 08477 say_and_wait(chan, vms->oldmessages, chan->language) || 08478 ast_play_and_wait(chan, "vm-vecchi") || 08479 ast_play_and_wait(chan, "vm-messages"); 08480 } 08481 return res; 08482 }
| static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| const char | message_gender[] | |||
| ) | [static] |
Definition at line 8286 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().
08287 { 08288 int res; 08289 int lastnum = 0; 08290 08291 res = ast_play_and_wait(chan, "vm-youhave"); 08292 08293 if (!res && vms->newmessages) { 08294 lastnum = vms->newmessages; 08295 08296 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08297 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08298 } 08299 08300 if (!res && vms->oldmessages) { 08301 res = ast_play_and_wait(chan, "vm-and"); 08302 } 08303 } 08304 08305 if (!res && vms->oldmessages) { 08306 lastnum = vms->oldmessages; 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-old", message_gender); 08310 } 08311 } 08312 08313 if (!res) { 08314 if (lastnum == 0) { 08315 res = ast_play_and_wait(chan, "vm-no"); 08316 } 08317 if (!res) { 08318 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08319 } 08320 } 08321 08322 return res; 08323 }
| static int vm_intro_nl | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8834 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().
08835 { 08836 /* Introduce messages they have */ 08837 int res; 08838 res = ast_play_and_wait(chan, "vm-youhave"); 08839 if (!res) { 08840 if (vms->newmessages) { 08841 res = say_and_wait(chan, vms->newmessages, chan->language); 08842 if (!res) { 08843 if (vms->newmessages == 1) 08844 res = ast_play_and_wait(chan, "vm-INBOXs"); 08845 else 08846 res = ast_play_and_wait(chan, "vm-INBOX"); 08847 } 08848 if (vms->oldmessages && !res) 08849 res = ast_play_and_wait(chan, "vm-and"); 08850 else if (!res) { 08851 if ((vms->newmessages == 1)) 08852 res = ast_play_and_wait(chan, "vm-message"); 08853 else 08854 res = ast_play_and_wait(chan, "vm-messages"); 08855 } 08856 08857 } 08858 if (!res && vms->oldmessages) { 08859 res = say_and_wait(chan, vms->oldmessages, chan->language); 08860 if (!res) { 08861 if (vms->oldmessages == 1) 08862 res = ast_play_and_wait(chan, "vm-Olds"); 08863 else 08864 res = ast_play_and_wait(chan, "vm-Old"); 08865 } 08866 if (!res) { 08867 if (vms->oldmessages == 1) 08868 res = ast_play_and_wait(chan, "vm-message"); 08869 else 08870 res = ast_play_and_wait(chan, "vm-messages"); 08871 } 08872 } 08873 if (!res) { 08874 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08875 res = ast_play_and_wait(chan, "vm-no"); 08876 if (!res) 08877 res = ast_play_and_wait(chan, "vm-messages"); 08878 } 08879 } 08880 } 08881 return res; 08882 }
| static int vm_intro_no | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8600 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().
08601 { 08602 /* Introduce messages they have */ 08603 int res; 08604 08605 res = ast_play_and_wait(chan, "vm-youhave"); 08606 if (res) 08607 return res; 08608 08609 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08610 res = ast_play_and_wait(chan, "vm-no"); 08611 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08612 return res; 08613 } 08614 08615 if (vms->newmessages) { 08616 if ((vms->newmessages == 1)) { 08617 res = ast_play_and_wait(chan, "digits/1"); 08618 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08619 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08620 } else { 08621 res = say_and_wait(chan, vms->newmessages, chan->language); 08622 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08623 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08624 } 08625 if (!res && vms->oldmessages) 08626 res = ast_play_and_wait(chan, "vm-and"); 08627 } 08628 if (!res && vms->oldmessages) { 08629 if (vms->oldmessages == 1) { 08630 res = ast_play_and_wait(chan, "digits/1"); 08631 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08632 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08633 } else { 08634 res = say_and_wait(chan, vms->oldmessages, chan->language); 08635 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08636 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08637 } 08638 } 08639 08640 return res; 08641 }
| static int vm_intro_pl | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8485 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08486 { 08487 /* Introduce messages they have */ 08488 int res; 08489 div_t num; 08490 08491 if (!vms->oldmessages && !vms->newmessages) { 08492 res = ast_play_and_wait(chan, "vm-no"); 08493 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08494 return res; 08495 } else { 08496 res = ast_play_and_wait(chan, "vm-youhave"); 08497 } 08498 08499 if (vms->newmessages) { 08500 num = div(vms->newmessages, 10); 08501 if (vms->newmessages == 1) { 08502 res = ast_play_and_wait(chan, "digits/1-a"); 08503 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08504 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08505 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08506 if (num.rem == 2) { 08507 if (!num.quot) { 08508 res = ast_play_and_wait(chan, "digits/2-ie"); 08509 } else { 08510 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08511 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08512 } 08513 } else { 08514 res = say_and_wait(chan, vms->newmessages, chan->language); 08515 } 08516 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08517 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08518 } else { 08519 res = say_and_wait(chan, vms->newmessages, chan->language); 08520 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08521 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08522 } 08523 if (!res && vms->oldmessages) 08524 res = ast_play_and_wait(chan, "vm-and"); 08525 } 08526 if (!res && vms->oldmessages) { 08527 num = div(vms->oldmessages, 10); 08528 if (vms->oldmessages == 1) { 08529 res = ast_play_and_wait(chan, "digits/1-a"); 08530 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08531 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08532 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08533 if (num.rem == 2) { 08534 if (!num.quot) { 08535 res = ast_play_and_wait(chan, "digits/2-ie"); 08536 } else { 08537 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08538 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08539 } 08540 } else { 08541 res = say_and_wait(chan, vms->oldmessages, chan->language); 08542 } 08543 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08544 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08545 } else { 08546 res = say_and_wait(chan, vms->oldmessages, chan->language); 08547 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08548 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08549 } 08550 } 08551 08552 return res; 08553 }
| static int vm_intro_pt | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8885 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().
08886 { 08887 /* Introduce messages they have */ 08888 int res; 08889 res = ast_play_and_wait(chan, "vm-youhave"); 08890 if (!res) { 08891 if (vms->newmessages) { 08892 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08893 if (!res) { 08894 if ((vms->newmessages == 1)) { 08895 res = ast_play_and_wait(chan, "vm-message"); 08896 if (!res) 08897 res = ast_play_and_wait(chan, "vm-INBOXs"); 08898 } else { 08899 res = ast_play_and_wait(chan, "vm-messages"); 08900 if (!res) 08901 res = ast_play_and_wait(chan, "vm-INBOX"); 08902 } 08903 } 08904 if (vms->oldmessages && !res) 08905 res = ast_play_and_wait(chan, "vm-and"); 08906 } 08907 if (!res && vms->oldmessages) { 08908 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08909 if (!res) { 08910 if (vms->oldmessages == 1) { 08911 res = ast_play_and_wait(chan, "vm-message"); 08912 if (!res) 08913 res = ast_play_and_wait(chan, "vm-Olds"); 08914 } else { 08915 res = ast_play_and_wait(chan, "vm-messages"); 08916 if (!res) 08917 res = ast_play_and_wait(chan, "vm-Old"); 08918 } 08919 } 08920 } 08921 if (!res) { 08922 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08923 res = ast_play_and_wait(chan, "vm-no"); 08924 if (!res) 08925 res = ast_play_and_wait(chan, "vm-messages"); 08926 } 08927 } 08928 } 08929 return res; 08930 }
| static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8746 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().
08746 { 08747 /* Introduce messages they have */ 08748 int res; 08749 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08750 res = ast_play_and_wait(chan, "vm-nomessages"); 08751 return res; 08752 } else { 08753 res = ast_play_and_wait(chan, "vm-youhave"); 08754 } 08755 if (vms->newmessages) { 08756 if (!res) 08757 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08758 if ((vms->newmessages == 1)) { 08759 if (!res) 08760 res = ast_play_and_wait(chan, "vm-message"); 08761 if (!res) 08762 res = ast_play_and_wait(chan, "vm-INBOXs"); 08763 } else { 08764 if (!res) 08765 res = ast_play_and_wait(chan, "vm-messages"); 08766 if (!res) 08767 res = ast_play_and_wait(chan, "vm-INBOX"); 08768 } 08769 if (vms->oldmessages && !res) 08770 res = ast_play_and_wait(chan, "vm-and"); 08771 } 08772 if (vms->oldmessages) { 08773 if (!res) 08774 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08775 if (vms->oldmessages == 1) { 08776 if (!res) 08777 res = ast_play_and_wait(chan, "vm-message"); 08778 if (!res) 08779 res = ast_play_and_wait(chan, "vm-Olds"); 08780 } else { 08781 if (!res) 08782 res = ast_play_and_wait(chan, "vm-messages"); 08783 if (!res) 08784 res = ast_play_and_wait(chan, "vm-Old"); 08785 } 08786 } 08787 return res; 08788 }
| static int vm_intro_se | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8556 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().
08557 { 08558 /* Introduce messages they have */ 08559 int res; 08560 08561 res = ast_play_and_wait(chan, "vm-youhave"); 08562 if (res) 08563 return res; 08564 08565 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08566 res = ast_play_and_wait(chan, "vm-no"); 08567 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08568 return res; 08569 } 08570 08571 if (vms->newmessages) { 08572 if ((vms->newmessages == 1)) { 08573 res = ast_play_and_wait(chan, "digits/ett"); 08574 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08575 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08576 } else { 08577 res = say_and_wait(chan, vms->newmessages, chan->language); 08578 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08579 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08580 } 08581 if (!res && vms->oldmessages) 08582 res = ast_play_and_wait(chan, "vm-and"); 08583 } 08584 if (!res && vms->oldmessages) { 08585 if (vms->oldmessages == 1) { 08586 res = ast_play_and_wait(chan, "digits/ett"); 08587 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08588 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08589 } else { 08590 res = say_and_wait(chan, vms->oldmessages, chan->language); 08591 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08592 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08593 } 08594 } 08595 08596 return res; 08597 }
| static int vm_intro_vi | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 9048 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
09049 { 09050 int res; 09051 09052 /* Introduce messages they have */ 09053 res = ast_play_and_wait(chan, "vm-youhave"); 09054 if (!res) { 09055 if (vms->newmessages) { 09056 res = say_and_wait(chan, vms->newmessages, chan->language); 09057 if (!res) 09058 res = ast_play_and_wait(chan, "vm-INBOX"); 09059 if (vms->oldmessages && !res) 09060 res = ast_play_and_wait(chan, "vm-and"); 09061 } 09062 if (!res && vms->oldmessages) { 09063 res = say_and_wait(chan, vms->oldmessages, chan->language); 09064 if (!res) 09065 res = ast_play_and_wait(chan, "vm-Old"); 09066 } 09067 if (!res) { 09068 if (!vms->oldmessages && !vms->newmessages) { 09069 res = ast_play_and_wait(chan, "vm-no"); 09070 if (!res) 09071 res = ast_play_and_wait(chan, "vm-message"); 09072 } 09073 } 09074 } 09075 return res; 09076 }
| static int vm_intro_zh | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 9009 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
09010 { 09011 int res; 09012 /* Introduce messages they have */ 09013 res = ast_play_and_wait(chan, "vm-you"); 09014 09015 if (!res && vms->newmessages) { 09016 res = ast_play_and_wait(chan, "vm-have"); 09017 if (!res) 09018 res = say_and_wait(chan, vms->newmessages, chan->language); 09019 if (!res) 09020 res = ast_play_and_wait(chan, "vm-tong"); 09021 if (!res) 09022 res = ast_play_and_wait(chan, "vm-INBOX"); 09023 if (vms->oldmessages && !res) 09024 res = ast_play_and_wait(chan, "vm-and"); 09025 else if (!res) 09026 res = ast_play_and_wait(chan, "vm-messages"); 09027 } 09028 if (!res && vms->oldmessages) { 09029 res = ast_play_and_wait(chan, "vm-have"); 09030 if (!res) 09031 res = say_and_wait(chan, vms->oldmessages, chan->language); 09032 if (!res) 09033 res = ast_play_and_wait(chan, "vm-tong"); 09034 if (!res) 09035 res = ast_play_and_wait(chan, "vm-Old"); 09036 if (!res) 09037 res = ast_play_and_wait(chan, "vm-messages"); 09038 } 09039 if (!res && !vms->oldmessages && !vms->newmessages) { 09040 res = ast_play_and_wait(chan, "vm-haveno"); 09041 if (!res) 09042 res = ast_play_and_wait(chan, "vm-messages"); 09043 } 09044 return res; 09045 }
| 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 3291 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().
03292 { 03293 switch (ast_lock_path(path)) { 03294 case AST_LOCK_TIMEOUT: 03295 return -1; 03296 default: 03297 return 0; 03298 } 03299 }
| static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1682 of file app_voicemail.c.
References my_umask, and VOICEMAIL_FILE_MODE.
Referenced by sendmail(), and sendpage().
01683 { 01684 FILE *p = NULL; 01685 int pfd = mkstemp(template); 01686 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01687 if (pfd > -1) { 01688 p = fdopen(pfd, "w+"); 01689 if (!p) { 01690 close(pfd); 01691 pfd = -1; 01692 } 01693 } 01694 return p; 01695 }
| 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 9262 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().
09263 { 09264 int cmd = 0; 09265 int duration = 0; 09266 int tries = 0; 09267 char newpassword[80] = ""; 09268 char newpassword2[80] = ""; 09269 char prefile[PATH_MAX] = ""; 09270 unsigned char buf[256]; 09271 int bytes = 0; 09272 09273 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09274 if (ast_adsi_available(chan)) { 09275 bytes += adsi_logo(buf + bytes); 09276 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09277 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09278 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09279 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09280 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09281 } 09282 09283 /* If forcename is set, have the user record their name */ 09284 if (ast_test_flag(vmu, VM_FORCENAME)) { 09285 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09286 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09287 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09288 if (cmd < 0 || cmd == 't' || cmd == '#') 09289 return cmd; 09290 } 09291 } 09292 09293 /* If forcegreetings is set, have the user record their greetings */ 09294 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09295 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09296 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09297 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09298 if (cmd < 0 || cmd == 't' || cmd == '#') 09299 return cmd; 09300 } 09301 09302 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09303 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09304 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09305 if (cmd < 0 || cmd == 't' || cmd == '#') 09306 return cmd; 09307 } 09308 } 09309 09310 /* 09311 * Change the password last since new users will be able to skip over any steps this one comes before 09312 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09313 */ 09314 for (;;) { 09315 newpassword[1] = '\0'; 09316 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09317 if (cmd == '#') 09318 newpassword[0] = '\0'; 09319 if (cmd < 0 || cmd == 't' || cmd == '#') 09320 return cmd; 09321 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09322 if (cmd < 0 || cmd == 't' || cmd == '#') 09323 return cmd; 09324 cmd = check_password(vmu, newpassword); /* perform password validation */ 09325 if (cmd != 0) { 09326 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09327 cmd = ast_play_and_wait(chan, vm_invalid_password); 09328 } else { 09329 newpassword2[1] = '\0'; 09330 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09331 if (cmd == '#') 09332 newpassword2[0] = '\0'; 09333 if (cmd < 0 || cmd == 't' || cmd == '#') 09334 return cmd; 09335 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09336 if (cmd < 0 || cmd == 't' || cmd == '#') 09337 return cmd; 09338 if (!strcmp(newpassword, newpassword2)) 09339 break; 09340 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09341 cmd = ast_play_and_wait(chan, vm_mismatch); 09342 } 09343 if (++tries == 3) 09344 return -1; 09345 if (cmd != 0) { 09346 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09347 } 09348 } 09349 if (pwdchange & PWDCHANGE_INTERNAL) 09350 vm_change_password(vmu, newpassword); 09351 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09352 vm_change_password_shell(vmu, newpassword); 09353 09354 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09355 cmd = ast_play_and_wait(chan, vm_passchanged); 09356 09357 return cmd; 09358 }
| 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 9360 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().
09361 { 09362 int cmd = 0; 09363 int retries = 0; 09364 int duration = 0; 09365 char newpassword[80] = ""; 09366 char newpassword2[80] = ""; 09367 char prefile[PATH_MAX] = ""; 09368 unsigned char buf[256]; 09369 int bytes = 0; 09370 09371 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09372 if (ast_adsi_available(chan)) { 09373 bytes += adsi_logo(buf + bytes); 09374 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09375 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09376 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09377 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09378 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09379 } 09380 while ((cmd >= 0) && (cmd != 't')) { 09381 if (cmd) 09382 retries = 0; 09383 switch (cmd) { 09384 case '1': /* Record your unavailable message */ 09385 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09386 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09387 break; 09388 case '2': /* Record your busy message */ 09389 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09390 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09391 break; 09392 case '3': /* Record greeting */ 09393 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09394 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09395 break; 09396 case '4': /* manage the temporary greeting */ 09397 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09398 break; 09399 case '5': /* change password */ 09400 if (vmu->password[0] == '-') { 09401 cmd = ast_play_and_wait(chan, "vm-no"); 09402 break; 09403 } 09404 newpassword[1] = '\0'; 09405 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09406 if (cmd == '#') 09407 newpassword[0] = '\0'; 09408 else { 09409 if (cmd < 0) 09410 break; 09411 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09412 break; 09413 } 09414 } 09415 cmd = check_password(vmu, newpassword); /* perform password validation */ 09416 if (cmd != 0) { 09417 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09418 cmd = ast_play_and_wait(chan, vm_invalid_password); 09419 if (!cmd) { 09420 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09421 } 09422 break; 09423 } 09424 newpassword2[1] = '\0'; 09425 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09426 if (cmd == '#') 09427 newpassword2[0] = '\0'; 09428 else { 09429 if (cmd < 0) 09430 break; 09431 09432 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09433 break; 09434 } 09435 } 09436 if (strcmp(newpassword, newpassword2)) { 09437 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09438 cmd = ast_play_and_wait(chan, vm_mismatch); 09439 if (!cmd) { 09440 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09441 } 09442 break; 09443 } 09444 09445 if (pwdchange & PWDCHANGE_INTERNAL) { 09446 vm_change_password(vmu, newpassword); 09447 } 09448 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09449 vm_change_password_shell(vmu, newpassword); 09450 } 09451 09452 ast_debug(1, "User %s set password to %s of length %d\n", 09453 vms->username, newpassword, (int) strlen(newpassword)); 09454 cmd = ast_play_and_wait(chan, vm_passchanged); 09455 break; 09456 case '*': 09457 cmd = 't'; 09458 break; 09459 default: 09460 cmd = 0; 09461 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09462 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09463 if (ast_fileexists(prefile, NULL, NULL)) { 09464 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09465 } 09466 DISPOSE(prefile, -1); 09467 if (!cmd) { 09468 cmd = ast_play_and_wait(chan, "vm-options"); 09469 } 09470 if (!cmd) { 09471 cmd = ast_waitfordigit(chan, 6000); 09472 } 09473 if (!cmd) { 09474 retries++; 09475 } 09476 if (retries > 3) { 09477 cmd = 't'; 09478 } 09479 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09480 } 09481 } 09482 if (cmd == 't') 09483 cmd = 0; 09484 return cmd; 09485 }
| static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
| char * | mbox | |||
| ) | [static] |
Definition at line 8155 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().
08156 { 08157 int cmd; 08158 08159 if ( !strncasecmp(chan->language, "it", 2) || 08160 !strncasecmp(chan->language, "es", 2) || 08161 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08162 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08163 return cmd ? cmd : ast_play_and_wait(chan, box); 08164 } else if (!strncasecmp(chan->language, "gr", 2)) { 08165 return vm_play_folder_name_gr(chan, box); 08166 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08167 return ast_play_and_wait(chan, box); 08168 } else if (!strncasecmp(chan->language, "pl", 2)) { 08169 return vm_play_folder_name_pl(chan, box); 08170 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08171 return vm_play_folder_name_ua(chan, box); 08172 } else if (!strncasecmp(chan->language, "vi", 2)) { 08173 return ast_play_and_wait(chan, box); 08174 } else { /* Default English */ 08175 cmd = ast_play_and_wait(chan, box); 08176 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08177 } 08178 }
| static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 8108 of file app_voicemail.c.
References ast_alloca, and ast_play_and_wait().
Referenced by vm_play_folder_name().
08109 { 08110 int cmd; 08111 char *buf; 08112 08113 buf = ast_alloca(strlen(box) + 2); 08114 strcpy(buf, box); 08115 strcat(buf, "s"); 08116 08117 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08118 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08119 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08120 } else { 08121 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08122 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08123 } 08124 }
| static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 8126 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08127 { 08128 int cmd; 08129 08130 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08131 if (!strcasecmp(box, "vm-INBOX")) 08132 cmd = ast_play_and_wait(chan, "vm-new-e"); 08133 else 08134 cmd = ast_play_and_wait(chan, "vm-old-e"); 08135 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08136 } else { 08137 cmd = ast_play_and_wait(chan, "vm-messages"); 08138 return cmd ? cmd : ast_play_and_wait(chan, box); 08139 } 08140 }
| static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 8142 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08143 { 08144 int cmd; 08145 08146 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08147 cmd = ast_play_and_wait(chan, "vm-messages"); 08148 return cmd ? cmd : ast_play_and_wait(chan, box); 08149 } else { 08150 cmd = ast_play_and_wait(chan, box); 08151 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08152 } 08153 }
| 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 9503 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().
09504 { 09505 int cmd = 0; 09506 int retries = 0; 09507 int duration = 0; 09508 char prefile[PATH_MAX] = ""; 09509 unsigned char buf[256]; 09510 int bytes = 0; 09511 09512 if (ast_adsi_available(chan)) { 09513 bytes += adsi_logo(buf + bytes); 09514 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09515 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09516 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09517 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09518 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09519 } 09520 09521 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09522 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09523 while ((cmd >= 0) && (cmd != 't')) { 09524 if (cmd) 09525 retries = 0; 09526 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09527 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09528 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09529 if (cmd == -1) { 09530 break; 09531 } 09532 cmd = 't'; 09533 } else { 09534 switch (cmd) { 09535 case '1': 09536 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09537 break; 09538 case '2': 09539 DELETE(prefile, -1, prefile, vmu); 09540 ast_play_and_wait(chan, "vm-tempremoved"); 09541 cmd = 't'; 09542 break; 09543 case '*': 09544 cmd = 't'; 09545 break; 09546 default: 09547 cmd = ast_play_and_wait(chan, 09548 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09549 "vm-tempgreeting2" : "vm-tempgreeting"); 09550 if (!cmd) { 09551 cmd = ast_waitfordigit(chan, 6000); 09552 } 09553 if (!cmd) { 09554 retries++; 09555 } 09556 if (retries > 3) { 09557 cmd = 't'; 09558 } 09559 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09560 } 09561 } 09562 DISPOSE(prefile, -1); 09563 } 09564 if (cmd == 't') 09565 cmd = 0; 09566 return cmd; 09567 }
| static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 11455 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and vm_users_data_provider_get_helper().
11457 { 11458 struct ast_vm_user *user; 11459 11460 AST_LIST_LOCK(&users); 11461 AST_LIST_TRAVERSE(&users, user, list) { 11462 vm_users_data_provider_get_helper(search, data_root, user); 11463 } 11464 AST_LIST_UNLOCK(&users); 11465 11466 return 0; 11467 }
| 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 11408 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().
11410 { 11411 struct ast_data *data_user, *data_zone; 11412 struct ast_data *data_state; 11413 struct vm_zone *zone = NULL; 11414 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11415 char ext_context[256] = ""; 11416 11417 data_user = ast_data_add_node(data_root, "user"); 11418 if (!data_user) { 11419 return -1; 11420 } 11421 11422 ast_data_add_structure(ast_vm_user, data_user, user); 11423 11424 AST_LIST_LOCK(&zones); 11425 AST_LIST_TRAVERSE(&zones, zone, list) { 11426 if (!strcmp(zone->name, user->zonetag)) { 11427 break; 11428 } 11429 } 11430 AST_LIST_UNLOCK(&zones); 11431 11432 /* state */ 11433 data_state = ast_data_add_node(data_user, "state"); 11434 if (!data_state) { 11435 return -1; 11436 } 11437 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11438 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11439 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11440 ast_data_add_int(data_state, "newmsg", newmsg); 11441 ast_data_add_int(data_state, "oldmsg", oldmsg); 11442 11443 if (zone) { 11444 data_zone = ast_data_add_node(data_user, "zone"); 11445 ast_data_add_structure(vm_zone, data_zone, zone); 11446 } 11447 11448 if (!ast_data_search_match(search, data_user)) { 11449 ast_data_remove_node(data_root, data_user); 11450 } 11451 11452 return 0; 11453 }
| static int vmauthenticate | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 11094 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().
11095 { 11096 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11097 struct ast_vm_user vmus; 11098 char *options = NULL; 11099 int silent = 0, skipuser = 0; 11100 int res = -1; 11101 11102 if (data) { 11103 s = ast_strdupa(data); 11104 user = strsep(&s, ","); 11105 options = strsep(&s, ","); 11106 if (user) { 11107 s = user; 11108 user = strsep(&s, "@"); 11109 context = strsep(&s, ""); 11110 if (!ast_strlen_zero(user)) 11111 skipuser++; 11112 ast_copy_string(mailbox, user, sizeof(mailbox)); 11113 } 11114 } 11115 11116 if (options) { 11117 silent = (strchr(options, 's')) != NULL; 11118 } 11119 11120 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11121 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11122 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11123 ast_play_and_wait(chan, "auth-thankyou"); 11124 res = 0; 11125 } else if (mailbox[0] == '*') { 11126 /* user entered '*' */ 11127 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11128 res = 0; /* prevent hangup */ 11129 } 11130 } 11131 11132 return res; 11133 }
| static int vmsayname_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 12634 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().
12635 { 12636 char *context; 12637 char *args_copy; 12638 int res; 12639 12640 if (ast_strlen_zero(data)) { 12641 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n"); 12642 return -1; 12643 } 12644 12645 args_copy = ast_strdupa(data); 12646 if ((context = strchr(args_copy, '@'))) { 12647 *context++ = '\0'; 12648 } else { 12649 context = "default"; 12650 } 12651 12652 if ((res = sayname(chan, args_copy, context) < 0)) { 12653 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12654 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12655 if (!res) { 12656 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12657 } 12658 } 12659 12660 return res; 12661 }
| 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 4448 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().
04449 { 04450 const struct vm_zone *z = NULL; 04451 struct timeval t = ast_tvnow(); 04452 04453 /* Does this user have a timezone specified? */ 04454 if (!ast_strlen_zero(vmu->zonetag)) { 04455 /* Find the zone in the list */ 04456 AST_LIST_LOCK(&zones); 04457 AST_LIST_TRAVERSE(&zones, z, list) { 04458 if (!strcmp(z->name, vmu->zonetag)) 04459 break; 04460 } 04461 AST_LIST_UNLOCK(&zones); 04462 } 04463 ast_localtime(&t, tm, z ? z->timezone : NULL); 04464 return tm; 04465 }
| static int wait_file | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | file | |||
| ) | [static] |
Definition at line 7504 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().
07505 { 07506 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07507 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); 07508 }
| static int wait_file2 | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | file | |||
| ) | [static] |
Definition at line 7496 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().
07497 { 07498 int res; 07499 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07500 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07501 return res; 07502 }
| static int write_password_to_file | ( | const char * | secretfn, | |
| const char * | password | |||
| ) | [static] |
Definition at line 12601 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().
12601 { 12602 struct ast_config *conf; 12603 struct ast_category *cat; 12604 struct ast_variable *var; 12605 int res = -1; 12606 12607 if (!(conf = ast_config_new())) { 12608 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12609 return res; 12610 } 12611 if (!(cat = ast_category_new("general", "", 1))) { 12612 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12613 ast_config_destroy(conf); 12614 return res; 12615 } 12616 if (!(var = ast_variable_new("password", password, ""))) { 12617 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12618 ast_config_destroy(conf); 12619 ast_category_destroy(cat); 12620 return res; 12621 } 12622 ast_category_append(conf, cat); 12623 ast_variable_append(cat, var); 12624 if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12625 res = 0; 12626 } else { 12627 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12628 } 12629 12630 ast_config_destroy(conf); 12631 return res; 12632 }
char* addesc = "Comedian Mail" [static] |
Definition at line 776 of file app_voicemail.c.
Referenced by adsi_load_vmail().
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 903 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 904 of file app_voicemail.c.
Referenced by actual_load_config(), and adsi_load_vmail().
int adsiver = 1 [static] |
Definition at line 905 of file app_voicemail.c.
Referenced by actual_load_config(), adsi_begin(), and adsi_load_vmail().
char* app = "VoiceMail" [static] |
Definition at line 779 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* app2 = "VoiceMailMain" [static] |
Definition at line 782 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* app3 = "MailboxExists" [static] |
Definition at line 784 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* app4 = "VMAuthenticate" [static] |
Definition at line 785 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 889 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char charset[32] = "ISO-8859-1" [static] |
Definition at line 901 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 892 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 11333 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 888 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 895 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 906 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 896 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
char exitcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 890 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 756 of file app_voicemail.c.
Referenced by actual_load_config(), and check_password().
char ext_pass_cmd[128] [static] |
Definition at line 755 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 799 of file app_voicemail.c.
Referenced by actual_load_config(), and run_externnotify().
char fromstring[100] [static] |
Definition at line 899 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
struct ast_flags globalflags = {0} [static] |
Definition at line 884 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 928 of file app_voicemail.c.
Referenced by inprocess_count(), load_module(), and unload_module().
char listen_control_forward_key[12] [static] |
Definition at line 857 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_pause_key[12] [static] |
Definition at line 859 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_restart_key[12] [static] |
Definition at line 860 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_reverse_key[12] [static] |
Definition at line 858 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_stop_key[12] [static] |
Definition at line 861 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char locale[20] [static] |
Definition at line 792 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 11089 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
const char* const mailbox_folders[] [static] |
Definition at line 1718 of file app_voicemail.c.
Referenced by get_folder_by_name(), and mbox().
char mailcmd[160] [static] |
Definition at line 798 of file app_voicemail.c.
Referenced by actual_load_config(), manager_list_voicemail_users(), sendmail(), and sendpage().
int maxdeletedmsg [static] |
Definition at line 795 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
int maxgreet [static] |
Definition at line 805 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), vm_options(), and vm_tempgreeting().
int maxlogins [static] |
Definition at line 807 of file app_voicemail.c.
Referenced by actual_load_config(), and vm_execmain().
int maxmsg [static] |
Definition at line 794 of file app_voicemail.c.
Referenced by actual_load_config(), copy_message(), and populate_defaults().
int maxsilence [static] |
Definition at line 793 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 808 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 826 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 852 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 828 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
int my_umask [static] |
Definition at line 758 of file app_voicemail.c.
Referenced by add_email_attachment(), leave_voicemail(), load_module(), and vm_mkftemp().
char* pagerbody = NULL [static] |
Definition at line 897 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 907 of file app_voicemail.c.
Referenced by actual_load_config(), and sendpage().
char pagerfromstring[100] [static] |
Definition at line 900 of file app_voicemail.c.
Referenced by actual_load_config(), and sendpage().
char* pagersubject = NULL [static] |
Definition at line 898 of file app_voicemail.c.
Referenced by actual_load_config(), and sendpage().
int passwordlocation [static] |
Definition at line 809 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 821 of file app_voicemail.c.
Referenced by mb_poll_thread(), and stop_poll_thread().
unsigned int poll_freq [static] |
Polling frequency
Definition at line 816 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 813 of file app_voicemail.c.
Referenced by actual_load_config().
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 822 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 823 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 762 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
int saydurationminfo [static] |
Definition at line 886 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char* sayname_app = "VMSayName" [static] |
Definition at line 787 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char serveremail[80] [static] |
Definition at line 797 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 796 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 806 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 800 of file app_voicemail.c.
Referenced by actual_load_config(), and run_externnotify().
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 774 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 869 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 868 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 865 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 866 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 864 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 870 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 882 of file app_voicemail.c.
Referenced by actual_load_config(), and vm_forwardoptions().
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 867 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 753 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 11469 of file app_voicemail.c.
char vmfmts[80] [static] |
Definition at line 801 of file app_voicemail.c.
Referenced by actual_load_config(), forward_message(), leave_voicemail(), and vm_execmain().
int vmmaxsecs [static] |
Definition at line 804 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), and populate_defaults().
int vmminsecs [static] |
Definition at line 803 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), and populate_defaults().
double volgain [static] |
Definition at line 802 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char zonetag[80] [static] |
Definition at line 791 of file app_voicemail.c.
Referenced by actual_load_config(), build_peer(), and populate_defaults().
1.6.1