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 11362 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 11389 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 11065 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().
11066 { 11067 struct ast_vm_user svm; 11068 AST_DECLARE_APP_ARGS(arg, 11069 AST_APP_ARG(mbox); 11070 AST_APP_ARG(context); 11071 ); 11072 11073 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11074 11075 if (ast_strlen_zero(arg.mbox)) { 11076 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11077 return -1; 11078 } 11079 11080 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11081 return 0; 11082 }
| static int actual_load_config | ( | int | reload, | |
| struct ast_config * | cfg, | |||
| struct ast_config * | ucfg | |||
| ) | [static] |
Definition at line 11899 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().
11900 { 11901 struct ast_vm_user *current; 11902 char *cat; 11903 struct ast_variable *var; 11904 const char *val; 11905 char *q, *stringp, *tmp; 11906 int x; 11907 unsigned int tmpadsi[4]; 11908 char secretfn[PATH_MAX] = ""; 11909 11910 #ifdef IMAP_STORAGE 11911 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11912 #endif 11913 /* set audio control prompts */ 11914 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11915 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11916 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11917 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11918 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11919 11920 /* Free all the users structure */ 11921 free_vm_users(); 11922 11923 /* Free all the zones structure */ 11924 free_vm_zones(); 11925 11926 AST_LIST_LOCK(&users); 11927 11928 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11929 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11930 11931 if (cfg) { 11932 /* General settings */ 11933 11934 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11935 val = "default"; 11936 ast_copy_string(userscontext, val, sizeof(userscontext)); 11937 /* Attach voice message to mail message ? */ 11938 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11939 val = "yes"; 11940 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11941 11942 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11943 val = "no"; 11944 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11945 11946 volgain = 0.0; 11947 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11948 sscanf(val, "%30lf", &volgain); 11949 11950 #ifdef ODBC_STORAGE 11951 strcpy(odbc_database, "asterisk"); 11952 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11953 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11954 } 11955 strcpy(odbc_table, "voicemessages"); 11956 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11957 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11958 } 11959 #endif 11960 /* Mail command */ 11961 strcpy(mailcmd, SENDMAIL); 11962 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11963 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11964 11965 maxsilence = 0; 11966 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11967 maxsilence = atoi(val); 11968 if (maxsilence > 0) 11969 maxsilence *= 1000; 11970 } 11971 11972 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11973 maxmsg = MAXMSG; 11974 } else { 11975 maxmsg = atoi(val); 11976 if (maxmsg < 0) { 11977 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11978 maxmsg = MAXMSG; 11979 } else if (maxmsg > MAXMSGLIMIT) { 11980 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11981 maxmsg = MAXMSGLIMIT; 11982 } 11983 } 11984 11985 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11986 maxdeletedmsg = 0; 11987 } else { 11988 if (sscanf(val, "%30d", &x) == 1) 11989 maxdeletedmsg = x; 11990 else if (ast_true(val)) 11991 maxdeletedmsg = MAXMSG; 11992 else 11993 maxdeletedmsg = 0; 11994 11995 if (maxdeletedmsg < 0) { 11996 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11997 maxdeletedmsg = MAXMSG; 11998 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11999 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 12000 maxdeletedmsg = MAXMSGLIMIT; 12001 } 12002 } 12003 12004 /* Load date format config for voicemail mail */ 12005 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 12006 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 12007 } 12008 12009 /* Load date format config for voicemail pager mail */ 12010 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 12011 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 12012 } 12013 12014 /* External password changing command */ 12015 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 12016 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12017 pwdchange = PWDCHANGE_EXTERNAL; 12018 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 12019 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12020 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 12021 } 12022 12023 /* External password validation command */ 12024 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 12025 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 12026 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 12027 } 12028 12029 #ifdef IMAP_STORAGE 12030 /* IMAP server address */ 12031 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 12032 ast_copy_string(imapserver, val, sizeof(imapserver)); 12033 } else { 12034 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 12035 } 12036 /* IMAP server port */ 12037 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 12038 ast_copy_string(imapport, val, sizeof(imapport)); 12039 } else { 12040 ast_copy_string(imapport, "143", sizeof(imapport)); 12041 } 12042 /* IMAP server flags */ 12043 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 12044 ast_copy_string(imapflags, val, sizeof(imapflags)); 12045 } 12046 /* IMAP server master username */ 12047 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 12048 ast_copy_string(authuser, val, sizeof(authuser)); 12049 } 12050 /* IMAP server master password */ 12051 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 12052 ast_copy_string(authpassword, val, sizeof(authpassword)); 12053 } 12054 /* Expunge on exit */ 12055 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 12056 if (ast_false(val)) 12057 expungeonhangup = 0; 12058 else 12059 expungeonhangup = 1; 12060 } else { 12061 expungeonhangup = 1; 12062 } 12063 /* IMAP voicemail folder */ 12064 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 12065 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12066 } else { 12067 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12068 } 12069 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12070 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12071 } 12072 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12073 imapgreetings = ast_true(val); 12074 } else { 12075 imapgreetings = 0; 12076 } 12077 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12078 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12079 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12080 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12081 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12082 } else { 12083 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12084 } 12085 12086 /* There is some very unorthodox casting done here. This is due 12087 * to the way c-client handles the argument passed in. It expects a 12088 * void pointer and casts the pointer directly to a long without 12089 * first dereferencing it. */ 12090 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12091 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12092 } else { 12093 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12094 } 12095 12096 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12097 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12098 } else { 12099 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12100 } 12101 12102 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12103 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12104 } else { 12105 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12106 } 12107 12108 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12109 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12110 } else { 12111 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12112 } 12113 12114 /* Increment configuration version */ 12115 imapversion++; 12116 #endif 12117 /* External voicemail notify application */ 12118 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12119 ast_copy_string(externnotify, val, sizeof(externnotify)); 12120 ast_debug(1, "found externnotify: %s\n", externnotify); 12121 } else { 12122 externnotify[0] = '\0'; 12123 } 12124 12125 /* SMDI voicemail notification */ 12126 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12127 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12128 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12129 smdi_iface = ast_smdi_interface_find(val); 12130 } else { 12131 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12132 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12133 } 12134 if (!smdi_iface) { 12135 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12136 } 12137 } 12138 12139 /* Silence treshold */ 12140 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12141 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12142 silencethreshold = atoi(val); 12143 12144 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12145 val = ASTERISK_USERNAME; 12146 ast_copy_string(serveremail, val, sizeof(serveremail)); 12147 12148 vmmaxsecs = 0; 12149 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12150 if (sscanf(val, "%30d", &x) == 1) { 12151 vmmaxsecs = x; 12152 } else { 12153 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12154 } 12155 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12156 static int maxmessage_deprecate = 0; 12157 if (maxmessage_deprecate == 0) { 12158 maxmessage_deprecate = 1; 12159 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12160 } 12161 if (sscanf(val, "%30d", &x) == 1) { 12162 vmmaxsecs = x; 12163 } else { 12164 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12165 } 12166 } 12167 12168 vmminsecs = 0; 12169 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12170 if (sscanf(val, "%30d", &x) == 1) { 12171 vmminsecs = x; 12172 if (maxsilence / 1000 >= vmminsecs) { 12173 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12174 } 12175 } else { 12176 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12177 } 12178 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12179 static int maxmessage_deprecate = 0; 12180 if (maxmessage_deprecate == 0) { 12181 maxmessage_deprecate = 1; 12182 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12183 } 12184 if (sscanf(val, "%30d", &x) == 1) { 12185 vmminsecs = x; 12186 if (maxsilence / 1000 >= vmminsecs) { 12187 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12188 } 12189 } else { 12190 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12191 } 12192 } 12193 12194 val = ast_variable_retrieve(cfg, "general", "format"); 12195 if (!val) { 12196 val = "wav"; 12197 } else { 12198 tmp = ast_strdupa(val); 12199 val = ast_format_str_reduce(tmp); 12200 if (!val) { 12201 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12202 val = "wav"; 12203 } 12204 } 12205 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12206 12207 skipms = 3000; 12208 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12209 if (sscanf(val, "%30d", &x) == 1) { 12210 maxgreet = x; 12211 } else { 12212 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12213 } 12214 } 12215 12216 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12217 if (sscanf(val, "%30d", &x) == 1) { 12218 skipms = x; 12219 } else { 12220 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12221 } 12222 } 12223 12224 maxlogins = 3; 12225 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12226 if (sscanf(val, "%30d", &x) == 1) { 12227 maxlogins = x; 12228 } else { 12229 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12230 } 12231 } 12232 12233 minpassword = MINPASSWORD; 12234 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12235 if (sscanf(val, "%30d", &x) == 1) { 12236 minpassword = x; 12237 } else { 12238 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12239 } 12240 } 12241 12242 /* Force new user to record name ? */ 12243 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12244 val = "no"; 12245 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12246 12247 /* Force new user to record greetings ? */ 12248 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12249 val = "no"; 12250 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12251 12252 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12253 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12254 stringp = ast_strdupa(val); 12255 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12256 if (!ast_strlen_zero(stringp)) { 12257 q = strsep(&stringp, ","); 12258 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12259 q++; 12260 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12261 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12262 } else { 12263 cidinternalcontexts[x][0] = '\0'; 12264 } 12265 } 12266 } 12267 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12268 ast_debug(1, "VM Review Option disabled globally\n"); 12269 val = "no"; 12270 } 12271 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12272 12273 /* Temporary greeting reminder */ 12274 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12275 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12276 val = "no"; 12277 } else { 12278 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12279 } 12280 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12281 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12282 ast_debug(1, "VM next message wrap disabled globally\n"); 12283 val = "no"; 12284 } 12285 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12286 12287 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12288 ast_debug(1, "VM Operator break disabled globally\n"); 12289 val = "no"; 12290 } 12291 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12292 12293 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12294 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12295 val = "no"; 12296 } 12297 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12298 12299 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12300 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12301 val = "no"; 12302 } 12303 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12304 12305 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12306 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12307 val = "yes"; 12308 } 12309 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12310 12311 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12312 ast_debug(1, "Move Heard enabled globally\n"); 12313 val = "yes"; 12314 } 12315 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12316 12317 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12318 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12319 val = "no"; 12320 } 12321 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12322 12323 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12324 ast_debug(1, "Duration info before msg enabled globally\n"); 12325 val = "yes"; 12326 } 12327 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12328 12329 saydurationminfo = 2; 12330 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12331 if (sscanf(val, "%30d", &x) == 1) { 12332 saydurationminfo = x; 12333 } else { 12334 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12335 } 12336 } 12337 12338 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12339 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12340 val = "no"; 12341 } 12342 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12343 12344 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12345 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12346 ast_debug(1, "found dialout context: %s\n", dialcontext); 12347 } else { 12348 dialcontext[0] = '\0'; 12349 } 12350 12351 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12352 ast_copy_string(callcontext, val, sizeof(callcontext)); 12353 ast_debug(1, "found callback context: %s\n", callcontext); 12354 } else { 12355 callcontext[0] = '\0'; 12356 } 12357 12358 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12359 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12360 ast_debug(1, "found operator context: %s\n", exitcontext); 12361 } else { 12362 exitcontext[0] = '\0'; 12363 } 12364 12365 /* load password sounds configuration */ 12366 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12367 ast_copy_string(vm_password, val, sizeof(vm_password)); 12368 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12369 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12370 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12371 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12372 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12373 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12374 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12375 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12376 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12377 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12378 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12379 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12380 } 12381 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12382 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12383 } 12384 /* load configurable audio prompts */ 12385 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12386 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12387 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12388 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12389 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12390 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12391 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12392 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12393 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12394 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12395 12396 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12397 val = "no"; 12398 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12399 12400 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12401 val = "voicemail.conf"; 12402 } 12403 if (!(strcmp(val, "spooldir"))) { 12404 passwordlocation = OPT_PWLOC_SPOOLDIR; 12405 } else { 12406 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12407 } 12408 12409 poll_freq = DEFAULT_POLL_FREQ; 12410 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12411 if (sscanf(val, "%30u", &poll_freq) != 1) { 12412 poll_freq = DEFAULT_POLL_FREQ; 12413 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12414 } 12415 } 12416 12417 poll_mailboxes = 0; 12418 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12419 poll_mailboxes = ast_true(val); 12420 12421 memset(fromstring, 0, sizeof(fromstring)); 12422 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12423 strcpy(charset, "ISO-8859-1"); 12424 if (emailbody) { 12425 ast_free(emailbody); 12426 emailbody = NULL; 12427 } 12428 if (emailsubject) { 12429 ast_free(emailsubject); 12430 emailsubject = NULL; 12431 } 12432 if (pagerbody) { 12433 ast_free(pagerbody); 12434 pagerbody = NULL; 12435 } 12436 if (pagersubject) { 12437 ast_free(pagersubject); 12438 pagersubject = NULL; 12439 } 12440 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12441 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12442 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12443 ast_copy_string(fromstring, val, sizeof(fromstring)); 12444 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12445 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12446 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12447 ast_copy_string(charset, val, sizeof(charset)); 12448 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12449 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12450 for (x = 0; x < 4; x++) { 12451 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12452 } 12453 } 12454 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12455 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12456 for (x = 0; x < 4; x++) { 12457 memcpy(&adsisec[x], &tmpadsi[x], 1); 12458 } 12459 } 12460 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12461 if (atoi(val)) { 12462 adsiver = atoi(val); 12463 } 12464 } 12465 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12466 ast_copy_string(zonetag, val, sizeof(zonetag)); 12467 } 12468 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12469 ast_copy_string(locale, val, sizeof(locale)); 12470 } 12471 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12472 emailsubject = ast_strdup(substitute_escapes(val)); 12473 } 12474 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12475 emailbody = ast_strdup(substitute_escapes(val)); 12476 } 12477 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12478 pagersubject = ast_strdup(substitute_escapes(val)); 12479 } 12480 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12481 pagerbody = ast_strdup(substitute_escapes(val)); 12482 } 12483 12484 /* load mailboxes from users.conf */ 12485 if (ucfg) { 12486 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12487 if (!strcasecmp(cat, "general")) { 12488 continue; 12489 } 12490 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12491 continue; 12492 if ((current = find_or_create(userscontext, cat))) { 12493 populate_defaults(current); 12494 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12495 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12496 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12497 current->passwordlocation = OPT_PWLOC_USERSCONF; 12498 } 12499 12500 switch (current->passwordlocation) { 12501 case OPT_PWLOC_SPOOLDIR: 12502 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12503 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12504 } 12505 } 12506 } 12507 } 12508 12509 /* load mailboxes from voicemail.conf */ 12510 cat = ast_category_browse(cfg, NULL); 12511 while (cat) { 12512 if (strcasecmp(cat, "general")) { 12513 var = ast_variable_browse(cfg, cat); 12514 if (strcasecmp(cat, "zonemessages")) { 12515 /* Process mailboxes in this context */ 12516 while (var) { 12517 append_mailbox(cat, var->name, var->value); 12518 var = var->next; 12519 } 12520 } else { 12521 /* Timezones in this context */ 12522 while (var) { 12523 struct vm_zone *z; 12524 if ((z = ast_malloc(sizeof(*z)))) { 12525 char *msg_format, *tzone; 12526 msg_format = ast_strdupa(var->value); 12527 tzone = strsep(&msg_format, "|,"); 12528 if (msg_format) { 12529 ast_copy_string(z->name, var->name, sizeof(z->name)); 12530 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12531 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12532 AST_LIST_LOCK(&zones); 12533 AST_LIST_INSERT_HEAD(&zones, z, list); 12534 AST_LIST_UNLOCK(&zones); 12535 } else { 12536 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12537 ast_free(z); 12538 } 12539 } else { 12540 AST_LIST_UNLOCK(&users); 12541 return -1; 12542 } 12543 var = var->next; 12544 } 12545 } 12546 } 12547 cat = ast_category_browse(cfg, cat); 12548 } 12549 12550 AST_LIST_UNLOCK(&users); 12551 12552 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12553 start_poll_thread(); 12554 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12555 stop_poll_thread();; 12556 12557 return 0; 12558 } else { 12559 AST_LIST_UNLOCK(&users); 12560 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12561 return 0; 12562 } 12563 }
| 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 13271 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().
13272 { 13273 int res = 0; 13274 char filename[PATH_MAX]; 13275 struct ast_config *msg_cfg = NULL; 13276 const char *origtime, *context; 13277 char *name, *num; 13278 int retries = 0; 13279 char *cid; 13280 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13281 13282 vms->starting = 0; 13283 13284 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13285 13286 /* Retrieve info from VM attribute file */ 13287 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13288 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13289 msg_cfg = ast_config_load(filename, config_flags); 13290 DISPOSE(vms->curdir, vms->curmsg); 13291 if (!valid_config(msg_cfg)) { 13292 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13293 return 0; 13294 } 13295 13296 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13297 ast_config_destroy(msg_cfg); 13298 return 0; 13299 } 13300 13301 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13302 13303 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13304 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13305 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13306 switch (option) { 13307 case 3: /* Play message envelope */ 13308 if (!res) 13309 res = play_message_datetime(chan, vmu, origtime, filename); 13310 if (!res) 13311 res = play_message_callerid(chan, vms, cid, context, 0); 13312 13313 res = 't'; 13314 break; 13315 13316 case 2: /* Call back */ 13317 13318 if (ast_strlen_zero(cid)) 13319 break; 13320 13321 ast_callerid_parse(cid, &name, &num); 13322 while ((res > -1) && (res != 't')) { 13323 switch (res) { 13324 case '1': 13325 if (num) { 13326 /* Dial the CID number */ 13327 res = dialout(chan, vmu, num, vmu->callback); 13328 if (res) { 13329 ast_config_destroy(msg_cfg); 13330 return 9; 13331 } 13332 } else { 13333 res = '2'; 13334 } 13335 break; 13336 13337 case '2': 13338 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13339 if (!ast_strlen_zero(vmu->dialout)) { 13340 res = dialout(chan, vmu, NULL, vmu->dialout); 13341 if (res) { 13342 ast_config_destroy(msg_cfg); 13343 return 9; 13344 } 13345 } else { 13346 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13347 res = ast_play_and_wait(chan, "vm-sorry"); 13348 } 13349 ast_config_destroy(msg_cfg); 13350 return res; 13351 case '*': 13352 res = 't'; 13353 break; 13354 case '3': 13355 case '4': 13356 case '5': 13357 case '6': 13358 case '7': 13359 case '8': 13360 case '9': 13361 case '0': 13362 13363 res = ast_play_and_wait(chan, "vm-sorry"); 13364 retries++; 13365 break; 13366 default: 13367 if (num) { 13368 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13369 res = ast_play_and_wait(chan, "vm-num-i-have"); 13370 if (!res) 13371 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13372 if (!res) 13373 res = ast_play_and_wait(chan, "vm-tocallnum"); 13374 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13375 if (!ast_strlen_zero(vmu->dialout)) { 13376 if (!res) 13377 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13378 } 13379 } else { 13380 res = ast_play_and_wait(chan, "vm-nonumber"); 13381 if (!ast_strlen_zero(vmu->dialout)) { 13382 if (!res) 13383 res = ast_play_and_wait(chan, "vm-toenternumber"); 13384 } 13385 } 13386 if (!res) { 13387 res = ast_play_and_wait(chan, "vm-star-cancel"); 13388 } 13389 if (!res) { 13390 res = ast_waitfordigit(chan, 6000); 13391 } 13392 if (!res) { 13393 retries++; 13394 if (retries > 3) { 13395 res = 't'; 13396 } 13397 } 13398 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13399 break; 13400 13401 } 13402 if (res == 't') 13403 res = 0; 13404 else if (res == '*') 13405 res = -1; 13406 } 13407 break; 13408 13409 case 1: /* Reply */ 13410 /* Send reply directly to sender */ 13411 if (ast_strlen_zero(cid)) 13412 break; 13413 13414 ast_callerid_parse(cid, &name, &num); 13415 if (!num) { 13416 ast_verb(3, "No CID number available, no reply sent\n"); 13417 if (!res) 13418 res = ast_play_and_wait(chan, "vm-nonumber"); 13419 ast_config_destroy(msg_cfg); 13420 return res; 13421 } else { 13422 struct ast_vm_user vmu2; 13423 if (find_user(&vmu2, vmu->context, num)) { 13424 struct leave_vm_options leave_options; 13425 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13426 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13427 13428 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13429 13430 memset(&leave_options, 0, sizeof(leave_options)); 13431 leave_options.record_gain = record_gain; 13432 res = leave_voicemail(chan, mailbox, &leave_options); 13433 if (!res) 13434 res = 't'; 13435 ast_config_destroy(msg_cfg); 13436 return res; 13437 } else { 13438 /* Sender has no mailbox, can't reply */ 13439 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13440 ast_play_and_wait(chan, "vm-nobox"); 13441 res = 't'; 13442 ast_config_destroy(msg_cfg); 13443 return res; 13444 } 13445 } 13446 res = 0; 13447 13448 break; 13449 } 13450 13451 ast_config_destroy(msg_cfg); 13452 13453 #ifndef IMAP_STORAGE 13454 if (!res) { 13455 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13456 vms->heard[msg] = 1; 13457 res = wait_file(chan, vms, vms->fn); 13458 } 13459 #endif 13460 return res; 13461 }
| static int append_mailbox | ( | const char * | context, | |
| const char * | box, | |||
| const char * | data | |||
| ) | [static] |
Definition at line 10792 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().
10793 { 10794 /* Assumes lock is already held */ 10795 char *tmp; 10796 char *stringp; 10797 char *s; 10798 struct ast_vm_user *vmu; 10799 char *mailbox_full; 10800 int new = 0, old = 0, urgent = 0; 10801 char secretfn[PATH_MAX] = ""; 10802 10803 tmp = ast_strdupa(data); 10804 10805 if (!(vmu = find_or_create(context, box))) 10806 return -1; 10807 10808 populate_defaults(vmu); 10809 10810 stringp = tmp; 10811 if ((s = strsep(&stringp, ","))) { 10812 if (!ast_strlen_zero(s) && s[0] == '*') { 10813 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10814 "\n\tmust be reset in voicemail.conf.\n", box); 10815 } 10816 /* assign password regardless of validity to prevent NULL password from being assigned */ 10817 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10818 } 10819 if (stringp && (s = strsep(&stringp, ","))) { 10820 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10821 } 10822 if (stringp && (s = strsep(&stringp, ","))) { 10823 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10824 } 10825 if (stringp && (s = strsep(&stringp, ","))) { 10826 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10827 } 10828 if (stringp && (s = strsep(&stringp, ","))) { 10829 apply_options(vmu, s); 10830 } 10831 10832 switch (vmu->passwordlocation) { 10833 case OPT_PWLOC_SPOOLDIR: 10834 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10835 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10836 } 10837 10838 mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1); 10839 strcpy(mailbox_full, box); 10840 strcat(mailbox_full, "@"); 10841 strcat(mailbox_full, context); 10842 10843 inboxcount2(mailbox_full, &urgent, &new, &old); 10844 queue_mwi_event(mailbox_full, urgent, new, old); 10845 10846 return 0; 10847 }
| 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 10849 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.
10850 { 10851 int res = 0; 10852 struct ast_vm_user *vmu; 10853 /* language parameter seems to only be used for display in manager action */ 10854 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10855 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10856 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10857 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10858 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10859 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10860 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10861 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10862 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10863 #ifdef IMAP_STORAGE 10864 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10865 "imapfolder=INBOX|imapvmshareid=6000"; 10866 #endif 10867 10868 switch (cmd) { 10869 case TEST_INIT: 10870 info->name = "vmuser"; 10871 info->category = "/apps/app_voicemail/"; 10872 info->summary = "Vmuser unit test"; 10873 info->description = 10874 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10875 return AST_TEST_NOT_RUN; 10876 case TEST_EXECUTE: 10877 break; 10878 } 10879 10880 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10881 return AST_TEST_NOT_RUN; 10882 } 10883 populate_defaults(vmu); 10884 ast_set_flag(vmu, VM_ALLOCED); 10885 10886 apply_options(vmu, options_string); 10887 10888 if (!ast_test_flag(vmu, VM_ATTACH)) { 10889 ast_test_status_update(test, "Parse failure for attach option\n"); 10890 res = 1; 10891 } 10892 if (strcasecmp(vmu->attachfmt, "wav49")) { 10893 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10894 res = 1; 10895 } 10896 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10897 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10898 res = 1; 10899 } 10900 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10901 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10902 res = 1; 10903 } 10904 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10905 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10906 res = 1; 10907 } 10908 if (strcasecmp(vmu->zonetag, "central")) { 10909 ast_test_status_update(test, "Parse failure for tz option\n"); 10910 res = 1; 10911 } 10912 if (!ast_test_flag(vmu, VM_DELETE)) { 10913 ast_test_status_update(test, "Parse failure for delete option\n"); 10914 res = 1; 10915 } 10916 if (!ast_test_flag(vmu, VM_SAYCID)) { 10917 ast_test_status_update(test, "Parse failure for saycid option\n"); 10918 res = 1; 10919 } 10920 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10921 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10922 res = 1; 10923 } 10924 if (!ast_test_flag(vmu, VM_REVIEW)) { 10925 ast_test_status_update(test, "Parse failure for review option\n"); 10926 res = 1; 10927 } 10928 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10929 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10930 res = 1; 10931 } 10932 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10933 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10934 res = 1; 10935 } 10936 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10937 ast_test_status_update(test, "Parse failure for operator option\n"); 10938 res = 1; 10939 } 10940 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10941 ast_test_status_update(test, "Parse failure for envelope option\n"); 10942 res = 1; 10943 } 10944 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10945 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10946 res = 1; 10947 } 10948 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10949 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10950 res = 1; 10951 } 10952 if (vmu->saydurationm != 5) { 10953 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10954 res = 1; 10955 } 10956 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10957 ast_test_status_update(test, "Parse failure for forcename option\n"); 10958 res = 1; 10959 } 10960 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10961 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10962 res = 1; 10963 } 10964 if (strcasecmp(vmu->callback, "somecontext")) { 10965 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10966 res = 1; 10967 } 10968 if (strcasecmp(vmu->dialout, "somecontext2")) { 10969 ast_test_status_update(test, "Parse failure for dialout option\n"); 10970 res = 1; 10971 } 10972 if (strcasecmp(vmu->exit, "somecontext3")) { 10973 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10974 res = 1; 10975 } 10976 if (vmu->minsecs != 10) { 10977 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10978 res = 1; 10979 } 10980 if (vmu->maxsecs != 100) { 10981 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10982 res = 1; 10983 } 10984 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10985 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10986 res = 1; 10987 } 10988 if (vmu->maxdeletedmsg != 50) { 10989 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10990 res = 1; 10991 } 10992 if (vmu->volgain != 1.3) { 10993 ast_test_status_update(test, "Parse failure for volgain option\n"); 10994 res = 1; 10995 } 10996 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10997 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10998 res = 1; 10999 } 11000 #ifdef IMAP_STORAGE 11001 apply_options(vmu, option_string2); 11002 11003 if (strcasecmp(vmu->imapuser, "imapuser")) { 11004 ast_test_status_update(test, "Parse failure for imapuser option\n"); 11005 res = 1; 11006 } 11007 if (strcasecmp(vmu->imappassword, "imappasswd")) { 11008 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 11009 res = 1; 11010 } 11011 if (strcasecmp(vmu->imapfolder, "INBOX")) { 11012 ast_test_status_update(test, "Parse failure for imapfolder option\n"); 11013 res = 1; 11014 } 11015 if (strcasecmp(vmu->imapvmshareid, "6000")) { 11016 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 11017 res = 1; 11018 } 11019 #endif 11020 11021 free_user(vmu); 11022 return res ? AST_TEST_FAIL : AST_TEST_PASS; 11023 }
| 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 7991 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().
07992 { 07993 int x = 0; 07994 int last_msg_idx = 0; 07995 07996 #ifndef IMAP_STORAGE 07997 int res = 0, nummsg; 07998 char fn2[PATH_MAX]; 07999 #endif 08000 08001 if (vms->lastmsg <= -1) { 08002 goto done; 08003 } 08004 08005 vms->curmsg = -1; 08006 #ifndef IMAP_STORAGE 08007 /* Get the deleted messages fixed */ 08008 if (vm_lock_path(vms->curdir)) { 08009 return ERROR_LOCK_PATH; 08010 } 08011 08012 /* update count as message may have arrived while we've got mailbox open */ 08013 last_msg_idx = last_message_index(vmu, vms->curdir); 08014 if (last_msg_idx != vms->lastmsg) { 08015 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 08016 } 08017 08018 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 08019 for (x = 0; x < last_msg_idx + 1; x++) { 08020 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 08021 /* Save this message. It's not in INBOX or hasn't been heard */ 08022 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08023 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 08024 break; 08025 } 08026 vms->curmsg++; 08027 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 08028 if (strcmp(vms->fn, fn2)) { 08029 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 08030 } 08031 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 08032 /* Move to old folder before deleting */ 08033 res = save_to_folder(vmu, vms, x, 1); 08034 if (res == ERROR_LOCK_PATH) { 08035 /* If save failed do not delete the message */ 08036 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 08037 vms->deleted[x] = 0; 08038 vms->heard[x] = 0; 08039 --x; 08040 } 08041 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 08042 /* Move to deleted folder */ 08043 res = save_to_folder(vmu, vms, x, 10); 08044 if (res == ERROR_LOCK_PATH) { 08045 /* If save failed do not delete the message */ 08046 vms->deleted[x] = 0; 08047 vms->heard[x] = 0; 08048 --x; 08049 } 08050 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 08051 /* If realtime storage enabled - we should explicitly delete this message, 08052 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08053 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08054 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08055 DELETE(vms->curdir, x, vms->fn, vmu); 08056 } 08057 } 08058 } 08059 08060 /* Delete ALL remaining messages */ 08061 nummsg = x - 1; 08062 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08063 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08064 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08065 DELETE(vms->curdir, x, vms->fn, vmu); 08066 } 08067 } 08068 ast_unlock_path(vms->curdir); 08069 #else /* defined(IMAP_STORAGE) */ 08070 ast_mutex_lock(&vms->lock); 08071 if (vms->deleted) { 08072 /* Since we now expunge after each delete, deleting in reverse order 08073 * ensures that no reordering occurs between each step. */ 08074 last_msg_idx = vms->dh_arraysize; 08075 for (x = last_msg_idx - 1; x >= 0; x--) { 08076 if (vms->deleted[x]) { 08077 ast_debug(3, "IMAP delete of %d\n", x); 08078 DELETE(vms->curdir, x, vms->fn, vmu); 08079 } 08080 } 08081 } 08082 #endif 08083 08084 done: 08085 if (vms->deleted) { 08086 ast_free(vms->deleted); 08087 vms->deleted = NULL; 08088 } 08089 if (vms->heard) { 08090 ast_free(vms->heard); 08091 vms->heard = NULL; 08092 } 08093 vms->dh_arraysize = 0; 08094 #ifdef IMAP_STORAGE 08095 ast_mutex_unlock(&vms->lock); 08096 #endif 08097 08098 return 0; 08099 }
| static char* complete_voicemail_show_users | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 11169 of file app_voicemail.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
11170 { 11171 int which = 0; 11172 int wordlen; 11173 struct ast_vm_user *vmu; 11174 const char *context = ""; 11175 11176 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11177 if (pos > 4) 11178 return NULL; 11179 if (pos == 3) 11180 return (state == 0) ? ast_strdup("for") : NULL; 11181 wordlen = strlen(word); 11182 AST_LIST_TRAVERSE(&users, vmu, list) { 11183 if (!strncasecmp(word, vmu->context, wordlen)) { 11184 if (context && strcmp(context, vmu->context) && ++which > state) 11185 return ast_strdup(vmu->context); 11186 /* ignore repeated contexts ? */ 11187 context = vmu->context; 11188 } 11189 } 11190 return NULL; 11191 }
| 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 13198 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().
13199 { 13200 int cmd = 0; 13201 char destination[80] = ""; 13202 int retries = 0; 13203 13204 if (!num) { 13205 ast_verb(3, "Destination number will be entered manually\n"); 13206 while (retries < 3 && cmd != 't') { 13207 destination[1] = '\0'; 13208 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13209 if (!cmd) 13210 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13211 if (!cmd) 13212 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13213 if (!cmd) { 13214 cmd = ast_waitfordigit(chan, 6000); 13215 if (cmd) 13216 destination[0] = cmd; 13217 } 13218 if (!cmd) { 13219 retries++; 13220 } else { 13221 13222 if (cmd < 0) 13223 return 0; 13224 if (cmd == '*') { 13225 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13226 return 0; 13227 } 13228 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13229 retries++; 13230 else 13231 cmd = 't'; 13232 } 13233 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13234 } 13235 if (retries >= 3) { 13236 return 0; 13237 } 13238 13239 } else { 13240 if (option_verbose > 2) 13241 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13242 ast_copy_string(destination, num, sizeof(destination)); 13243 } 13244 13245 if (!ast_strlen_zero(destination)) { 13246 if (destination[strlen(destination) -1 ] == '*') 13247 return 0; 13248 if (option_verbose > 2) 13249 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13250 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13251 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13252 chan->priority = 0; 13253 return 9; 13254 } 13255 return 0; 13256 }
| static struct ast_vm_user* find_or_create | ( | const char * | context, | |
| const char * | box | |||
| ) | [static, read] |
Definition at line 10752 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().
10753 { 10754 struct ast_vm_user *vmu; 10755 10756 if (!ast_strlen_zero(box) && box[0] == '*') { 10757 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10758 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10759 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10760 "\n\tand will be ignored.\n", box, context); 10761 return NULL; 10762 } 10763 10764 AST_LIST_TRAVERSE(&users, vmu, list) { 10765 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10766 if (strcasecmp(vmu->context, context)) { 10767 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10768 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10769 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10770 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10771 } 10772 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10773 return NULL; 10774 } 10775 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10776 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10777 return NULL; 10778 } 10779 } 10780 10781 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10782 return NULL; 10783 10784 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10785 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10786 10787 AST_LIST_INSERT_TAIL(&users, vmu, list); 10788 10789 return vmu; 10790 }
| 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 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07300 prompt_played++; 07301 if (res || prompt_played > 4) 07302 break; 07303 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07304 break; 07305 } 07306 07307 /* start all over if no username */ 07308 if (ast_strlen_zero(username)) 07309 continue; 07310 stringp = username; 07311 s = strsep(&stringp, "*"); 07312 /* start optimistic */ 07313 valid_extensions = 1; 07314 while (s) { 07315 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07316 int oldmsgs; 07317 int newmsgs; 07318 int capacity; 07319 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07320 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07321 /* Shouldn't happen, but allow trying another extension if it does */ 07322 res = ast_play_and_wait(chan, "pbx-invalid"); 07323 valid_extensions = 0; 07324 break; 07325 } 07326 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07327 if ((newmsgs + oldmsgs) >= capacity) { 07328 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07329 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07330 valid_extensions = 0; 07331 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07332 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07333 free_user(vmtmp); 07334 } 07335 inprocess_count(receiver->mailbox, receiver->context, -1); 07336 break; 07337 } 07338 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07339 } else { 07340 /* XXX Optimization for the future. When we encounter a single bad extension, 07341 * bailing out on all of the extensions may not be the way to go. We should 07342 * probably just bail on that single extension, then allow the user to enter 07343 * several more. XXX 07344 */ 07345 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07346 free_user(receiver); 07347 } 07348 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07349 /* "I am sorry, that's not a valid extension. Please try again." */ 07350 res = ast_play_and_wait(chan, "pbx-invalid"); 07351 valid_extensions = 0; 07352 break; 07353 } 07354 07355 /* play name if available, else play extension number */ 07356 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07357 RETRIEVE(fn, -1, s, receiver->context); 07358 if (ast_fileexists(fn, NULL, NULL) > 0) { 07359 res = ast_stream_and_wait(chan, fn, ecodes); 07360 if (res) { 07361 DISPOSE(fn, -1); 07362 return res; 07363 } 07364 } else { 07365 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07366 } 07367 DISPOSE(fn, -1); 07368 07369 s = strsep(&stringp, "*"); 07370 } 07371 /* break from the loop of reading the extensions */ 07372 if (valid_extensions) 07373 break; 07374 } 07375 /* check if we're clear to proceed */ 07376 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07377 return res; 07378 if (is_new_message == 1) { 07379 struct leave_vm_options leave_options; 07380 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07381 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07382 07383 /* Send VoiceMail */ 07384 memset(&leave_options, 0, sizeof(leave_options)); 07385 leave_options.record_gain = record_gain; 07386 cmd = leave_voicemail(chan, mailbox, &leave_options); 07387 } else { 07388 /* Forward VoiceMail */ 07389 long duration = 0; 07390 struct vm_state vmstmp; 07391 int copy_msg_result = 0; 07392 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07393 07394 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07395 07396 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07397 if (!cmd) { 07398 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07399 #ifdef IMAP_STORAGE 07400 int attach_user_voicemail; 07401 char *myserveremail = serveremail; 07402 07403 /* get destination mailbox */ 07404 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07405 if (!dstvms) { 07406 dstvms = create_vm_state_from_user(vmtmp); 07407 } 07408 if (dstvms) { 07409 init_mailstream(dstvms, 0); 07410 if (!dstvms->mailstream) { 07411 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07412 } else { 07413 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07414 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07415 } 07416 } else { 07417 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07418 } 07419 if (!ast_strlen_zero(vmtmp->serveremail)) 07420 myserveremail = vmtmp->serveremail; 07421 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07422 /* NULL category for IMAP storage */ 07423 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07424 dstvms->curbox, 07425 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07426 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07427 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07428 NULL, urgent_str); 07429 #else 07430 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07431 #endif 07432 saved_messages++; 07433 AST_LIST_REMOVE_CURRENT(list); 07434 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07435 free_user(vmtmp); 07436 if (res) 07437 break; 07438 } 07439 AST_LIST_TRAVERSE_SAFE_END; 07440 if (saved_messages > 0 && !copy_msg_result) { 07441 /* give confirmation that the message was saved */ 07442 /* commented out since we can't forward batches yet 07443 if (saved_messages == 1) 07444 res = ast_play_and_wait(chan, "vm-message"); 07445 else 07446 res = ast_play_and_wait(chan, "vm-messages"); 07447 if (!res) 07448 res = ast_play_and_wait(chan, "vm-saved"); */ 07449 #ifdef IMAP_STORAGE 07450 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07451 if (ast_strlen_zero(vmstmp.introfn)) 07452 #endif 07453 res = ast_play_and_wait(chan, "vm-msgsaved"); 07454 } 07455 #ifndef IMAP_STORAGE 07456 else { 07457 /* with IMAP, mailbox full warning played by imap_check_limits */ 07458 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07459 } 07460 /* Restore original message without prepended message if backup exists */ 07461 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07462 strcpy(textfile, msgfile); 07463 strcpy(backup, msgfile); 07464 strcpy(backup_textfile, msgfile); 07465 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07466 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07467 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07468 if (ast_fileexists(backup, NULL, NULL) > 0) { 07469 ast_filerename(backup, msgfile, NULL); 07470 rename(backup_textfile, textfile); 07471 } 07472 #endif 07473 } 07474 DISPOSE(dir, curmsg); 07475 #ifndef IMAP_STORAGE 07476 if (cmd) { /* assuming hangup, cleanup backup file */ 07477 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07478 strcpy(textfile, msgfile); 07479 strcpy(backup_textfile, msgfile); 07480 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07481 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07482 rename(backup_textfile, textfile); 07483 } 07484 #endif 07485 } 07486 07487 /* If anything failed above, we still have this list to free */ 07488 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07489 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07490 free_user(vmtmp); 07491 } 07492 return res ? res : cmd; 07493 }
| 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 11781 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().
11782 { 11783 struct ast_vm_user *current; 11784 AST_LIST_LOCK(&users); 11785 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11786 ast_set_flag(current, VM_ALLOCED); 11787 free_user(current); 11788 } 11789 AST_LIST_UNLOCK(&users); 11790 }
| static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11793 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().
11794 { 11795 struct vm_zone *zcur; 11796 AST_LIST_LOCK(&zones); 11797 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11798 free_zone(zcur); 11799 AST_LIST_UNLOCK(&zones); 11800 }
| 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 11551 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().
11552 { 11553 unsigned int len; 11554 struct mwi_sub *mwi_sub; 11555 struct mwi_sub_task *p = datap; 11556 11557 len = sizeof(*mwi_sub); 11558 if (!ast_strlen_zero(p->mailbox)) 11559 len += strlen(p->mailbox); 11560 11561 if (!ast_strlen_zero(p->context)) 11562 len += strlen(p->context) + 1; /* Allow for seperator */ 11563 11564 if (!(mwi_sub = ast_calloc(1, len))) 11565 return -1; 11566 11567 mwi_sub->uniqueid = p->uniqueid; 11568 if (!ast_strlen_zero(p->mailbox)) 11569 strcpy(mwi_sub->mailbox, p->mailbox); 11570 11571 if (!ast_strlen_zero(p->context)) { 11572 strcat(mwi_sub->mailbox, "@"); 11573 strcat(mwi_sub->mailbox, p->context); 11574 } 11575 11576 AST_RWLIST_WRLOCK(&mwi_subs); 11577 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11578 AST_RWLIST_UNLOCK(&mwi_subs); 11579 ast_free((void *) p->mailbox); 11580 ast_free((void *) p->context); 11581 ast_free(p); 11582 poll_subscribed_mailbox(mwi_sub); 11583 return 0; 11584 }
| static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11529 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().
11530 { 11531 struct mwi_sub *mwi_sub; 11532 uint32_t *uniqueid = datap; 11533 11534 AST_RWLIST_WRLOCK(&mwi_subs); 11535 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11536 if (mwi_sub->uniqueid == *uniqueid) { 11537 AST_LIST_REMOVE_CURRENT(entry); 11538 break; 11539 } 11540 } 11541 AST_RWLIST_TRAVERSE_SAFE_END 11542 AST_RWLIST_UNLOCK(&mwi_subs); 11543 11544 if (mwi_sub) 11545 mwi_sub_destroy(mwi_sub); 11546 11547 ast_free(uniqueid); 11548 return 0; 11549 }
| 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 11306 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.
11307 { 11308 switch (cmd) { 11309 case CLI_INIT: 11310 e->command = "voicemail reload"; 11311 e->usage = 11312 "Usage: voicemail reload\n" 11313 " Reload voicemail configuration\n"; 11314 return NULL; 11315 case CLI_GENERATE: 11316 return NULL; 11317 } 11318 11319 if (a->argc != 2) 11320 return CLI_SHOWUSAGE; 11321 11322 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11323 load_config(1); 11324 11325 return CLI_SUCCESS; 11326 }
| 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 11194 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.
11195 { 11196 struct ast_vm_user *vmu; 11197 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11198 const char *context = NULL; 11199 int users_counter = 0; 11200 11201 switch (cmd) { 11202 case CLI_INIT: 11203 e->command = "voicemail show users"; 11204 e->usage = 11205 "Usage: voicemail show users [for <context>]\n" 11206 " Lists all mailboxes currently set up\n"; 11207 return NULL; 11208 case CLI_GENERATE: 11209 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11210 } 11211 11212 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11213 return CLI_SHOWUSAGE; 11214 if (a->argc == 5) { 11215 if (strcmp(a->argv[3],"for")) 11216 return CLI_SHOWUSAGE; 11217 context = a->argv[4]; 11218 } 11219 11220 if (ast_check_realtime("voicemail")) { 11221 if (!context) { 11222 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11223 return CLI_SHOWUSAGE; 11224 } 11225 return show_users_realtime(a->fd, context); 11226 } 11227 11228 AST_LIST_LOCK(&users); 11229 if (AST_LIST_EMPTY(&users)) { 11230 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11231 AST_LIST_UNLOCK(&users); 11232 return CLI_FAILURE; 11233 } 11234 if (!context) { 11235 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11236 } else { 11237 int count = 0; 11238 AST_LIST_TRAVERSE(&users, vmu, list) { 11239 if (!strcmp(context, vmu->context)) { 11240 count++; 11241 break; 11242 } 11243 } 11244 if (count) { 11245 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11246 } else { 11247 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11248 AST_LIST_UNLOCK(&users); 11249 return CLI_FAILURE; 11250 } 11251 } 11252 AST_LIST_TRAVERSE(&users, vmu, list) { 11253 int newmsgs = 0, oldmsgs = 0; 11254 char count[12], tmp[256] = ""; 11255 11256 if (!context || !strcmp(context, vmu->context)) { 11257 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11258 inboxcount(tmp, &newmsgs, &oldmsgs); 11259 snprintf(count, sizeof(count), "%d", newmsgs); 11260 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11261 users_counter++; 11262 } 11263 } 11264 AST_LIST_UNLOCK(&users); 11265 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11266 return CLI_SUCCESS; 11267 }
| 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 11270 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.
11271 { 11272 struct vm_zone *zone; 11273 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11274 char *res = CLI_SUCCESS; 11275 11276 switch (cmd) { 11277 case CLI_INIT: 11278 e->command = "voicemail show zones"; 11279 e->usage = 11280 "Usage: voicemail show zones\n" 11281 " Lists zone message formats\n"; 11282 return NULL; 11283 case CLI_GENERATE: 11284 return NULL; 11285 } 11286 11287 if (a->argc != 3) 11288 return CLI_SHOWUSAGE; 11289 11290 AST_LIST_LOCK(&zones); 11291 if (!AST_LIST_EMPTY(&zones)) { 11292 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11293 AST_LIST_TRAVERSE(&zones, zone, list) { 11294 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11295 } 11296 } else { 11297 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11298 res = CLI_FAILURE; 11299 } 11300 AST_LIST_UNLOCK(&zones); 11301 11302 return res; 11303 }
| 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 11849 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().
11850 { 11851 struct ast_config *cfg, *ucfg; 11852 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11853 int res; 11854 11855 ast_unload_realtime("voicemail"); 11856 ast_unload_realtime("voicemail_data"); 11857 11858 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11859 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11860 return 0; 11861 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11862 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11863 ucfg = NULL; 11864 } 11865 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11866 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11867 ast_config_destroy(ucfg); 11868 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11869 return 0; 11870 } 11871 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11872 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11873 return 0; 11874 } else { 11875 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11876 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11877 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11878 ucfg = NULL; 11879 } 11880 } 11881 11882 res = actual_load_config(reload, cfg, ucfg); 11883 11884 ast_config_destroy(cfg); 11885 ast_config_destroy(ucfg); 11886 11887 return res; 11888 }
| static int load_module | ( | void | ) | [static] |
Definition at line 13150 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().
13151 { 13152 int res; 13153 my_umask = umask(0); 13154 umask(my_umask); 13155 13156 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13157 return AST_MODULE_LOAD_DECLINE; 13158 } 13159 13160 /* compute the location of the voicemail spool directory */ 13161 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13162 13163 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13164 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13165 } 13166 13167 if ((res = load_config(0))) 13168 return res; 13169 13170 res = ast_register_application_xml(app, vm_exec); 13171 res |= ast_register_application_xml(app2, vm_execmain); 13172 res |= ast_register_application_xml(app3, vm_box_exists); 13173 res |= ast_register_application_xml(app4, vmauthenticate); 13174 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13175 res |= ast_custom_function_register(&mailbox_exists_acf); 13176 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13177 #ifdef TEST_FRAMEWORK 13178 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13179 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13180 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13181 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13182 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13183 #endif 13184 13185 if (res) 13186 return res; 13187 13188 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13189 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13190 13191 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13192 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13193 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13194 13195 return res; 13196 }
| 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-%u-%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%u", 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 11680 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().
11681 { 11682 struct ast_vm_user *vmu = NULL; 11683 const char *id = astman_get_header(m, "ActionID"); 11684 char actionid[128] = ""; 11685 11686 if (!ast_strlen_zero(id)) 11687 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11688 11689 AST_LIST_LOCK(&users); 11690 11691 if (AST_LIST_EMPTY(&users)) { 11692 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11693 AST_LIST_UNLOCK(&users); 11694 return RESULT_SUCCESS; 11695 } 11696 11697 astman_send_ack(s, m, "Voicemail user list will follow"); 11698 11699 AST_LIST_TRAVERSE(&users, vmu, list) { 11700 char dirname[256]; 11701 11702 #ifdef IMAP_STORAGE 11703 int new, old; 11704 inboxcount(vmu->mailbox, &new, &old); 11705 #endif 11706 11707 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11708 astman_append(s, 11709 "%s" 11710 "Event: VoicemailUserEntry\r\n" 11711 "VMContext: %s\r\n" 11712 "VoiceMailbox: %s\r\n" 11713 "Fullname: %s\r\n" 11714 "Email: %s\r\n" 11715 "Pager: %s\r\n" 11716 "ServerEmail: %s\r\n" 11717 "MailCommand: %s\r\n" 11718 "Language: %s\r\n" 11719 "TimeZone: %s\r\n" 11720 "Callback: %s\r\n" 11721 "Dialout: %s\r\n" 11722 "UniqueID: %s\r\n" 11723 "ExitContext: %s\r\n" 11724 "SayDurationMinimum: %d\r\n" 11725 "SayEnvelope: %s\r\n" 11726 "SayCID: %s\r\n" 11727 "AttachMessage: %s\r\n" 11728 "AttachmentFormat: %s\r\n" 11729 "DeleteMessage: %s\r\n" 11730 "VolumeGain: %.2f\r\n" 11731 "CanReview: %s\r\n" 11732 "CallOperator: %s\r\n" 11733 "MaxMessageCount: %d\r\n" 11734 "MaxMessageLength: %d\r\n" 11735 "NewMessageCount: %d\r\n" 11736 #ifdef IMAP_STORAGE 11737 "OldMessageCount: %d\r\n" 11738 "IMAPUser: %s\r\n" 11739 #endif 11740 "\r\n", 11741 actionid, 11742 vmu->context, 11743 vmu->mailbox, 11744 vmu->fullname, 11745 vmu->email, 11746 vmu->pager, 11747 ast_strlen_zero(vmu->serveremail) ? serveremail : vmu->serveremail, 11748 mailcmd, 11749 vmu->language, 11750 vmu->zonetag, 11751 vmu->callback, 11752 vmu->dialout, 11753 vmu->uniqueid, 11754 vmu->exit, 11755 vmu->saydurationm, 11756 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11757 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11758 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11759 vmu->attachfmt, 11760 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11761 vmu->volgain, 11762 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11763 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11764 vmu->maxmsg, 11765 vmu->maxsecs, 11766 #ifdef IMAP_STORAGE 11767 new, old, vmu->imapuser 11768 #else 11769 count_messages(vmu, dirname) 11770 #endif 11771 ); 11772 } 11773 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11774 11775 AST_LIST_UNLOCK(&users); 11776 11777 return RESULT_SUCCESS; 11778 }
| static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11501 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().
11502 { 11503 while (poll_thread_run) { 11504 struct timespec ts = { 0, }; 11505 struct timeval wait; 11506 11507 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11508 ts.tv_sec = wait.tv_sec; 11509 ts.tv_nsec = wait.tv_usec * 1000; 11510 11511 ast_mutex_lock(&poll_lock); 11512 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11513 ast_mutex_unlock(&poll_lock); 11514 11515 if (!poll_thread_run) 11516 break; 11517 11518 poll_subscribed_mailboxes(); 11519 } 11520 11521 return NULL; 11522 }
| 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 11524 of file app_voicemail.c.
References ast_free.
Referenced by handle_unsubscribe().
11525 { 11526 ast_free(mwi_sub); 11527 }
| static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 11612 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().
11613 { 11614 struct mwi_sub_task *mwist; 11615 11616 if (ast_event_get_type(event) != AST_EVENT_SUB) 11617 return; 11618 11619 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11620 return; 11621 11622 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11623 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11624 return; 11625 } 11626 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11627 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11628 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11629 11630 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11631 ast_free(mwist); 11632 } 11633 }
| static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 11586 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().
11587 { 11588 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11589 11590 if (!uniqueid) { 11591 ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); 11592 return; 11593 } 11594 11595 if (ast_event_get_type(event) != AST_EVENT_UNSUB) { 11596 ast_free(uniqueid); 11597 return; 11598 } 11599 11600 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { 11601 ast_free(uniqueid); 11602 return; 11603 } 11604 11605 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11606 *uniqueid = u; 11607 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11608 ast_free(uniqueid); 11609 } 11610 }
| 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 7938 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().
07939 { 07940 int count_msg, last_msg; 07941 07942 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07943 07944 /* Rename the member vmbox HERE so that we don't try to return before 07945 * we know what's going on. 07946 */ 07947 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07948 07949 /* Faster to make the directory than to check if it exists. */ 07950 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07951 07952 /* traverses directory using readdir (or select query for ODBC) */ 07953 count_msg = count_messages(vmu, vms->curdir); 07954 if (count_msg < 0) { 07955 return count_msg; 07956 } else { 07957 vms->lastmsg = count_msg - 1; 07958 } 07959 07960 if (vm_allocate_dh(vms, vmu, count_msg)) { 07961 return -1; 07962 } 07963 07964 /* 07965 The following test is needed in case sequencing gets messed up. 07966 There appears to be more than one way to mess up sequence, so 07967 we will not try to find all of the root causes--just fix it when 07968 detected. 07969 */ 07970 07971 if (vm_lock_path(vms->curdir)) { 07972 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07973 return ERROR_LOCK_PATH; 07974 } 07975 07976 /* for local storage, checks directory for messages up to maxmsg limit */ 07977 last_msg = last_message_index(vmu, vms->curdir); 07978 ast_unlock_path(vms->curdir); 07979 07980 if (last_msg < -1) { 07981 return last_msg; 07982 } else if (vms->lastmsg != last_msg) { 07983 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); 07984 resequence_mailbox(vmu, vms->curdir, count_msg); 07985 } 07986 07987 return 0; 07988 }
| static int play_message | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7712 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().
07713 { 07714 int res = 0; 07715 char filename[256], *cid; 07716 const char *origtime, *context, *category, *duration, *flag; 07717 struct ast_config *msg_cfg; 07718 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07719 07720 vms->starting = 0; 07721 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07722 adsi_message(chan, vms); 07723 if (!vms->curmsg) { 07724 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07725 } else if (vms->curmsg == vms->lastmsg) { 07726 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07727 } 07728 07729 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07730 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07731 msg_cfg = ast_config_load(filename, config_flags); 07732 if (!valid_config(msg_cfg)) { 07733 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07734 return 0; 07735 } 07736 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07737 07738 /* Play the word urgent if we are listening to urgent messages */ 07739 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07740 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07741 } 07742 07743 if (!res) { 07744 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07745 /* POLISH syntax */ 07746 if (!strncasecmp(chan->language, "pl", 2)) { 07747 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07748 int ten, one; 07749 char nextmsg[256]; 07750 ten = (vms->curmsg + 1) / 10; 07751 one = (vms->curmsg + 1) % 10; 07752 07753 if (vms->curmsg < 20) { 07754 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07755 res = wait_file2(chan, vms, nextmsg); 07756 } else { 07757 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07758 res = wait_file2(chan, vms, nextmsg); 07759 if (one > 0) { 07760 if (!res) { 07761 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07762 res = wait_file2(chan, vms, nextmsg); 07763 } 07764 } 07765 } 07766 } 07767 if (!res) 07768 res = wait_file2(chan, vms, "vm-message"); 07769 /* HEBREW syntax */ 07770 } else if (!strncasecmp(chan->language, "he", 2)) { 07771 if (!vms->curmsg) { 07772 res = wait_file2(chan, vms, "vm-message"); 07773 res = wait_file2(chan, vms, "vm-first"); 07774 } else if (vms->curmsg == vms->lastmsg) { 07775 res = wait_file2(chan, vms, "vm-message"); 07776 res = wait_file2(chan, vms, "vm-last"); 07777 } else { 07778 res = wait_file2(chan, vms, "vm-message"); 07779 res = wait_file2(chan, vms, "vm-number"); 07780 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07781 } 07782 /* VIETNAMESE syntax */ 07783 } else if (!strncasecmp(chan->language, "vi", 2)) { 07784 if (!vms->curmsg) { 07785 res = wait_file2(chan, vms, "vm-message"); 07786 res = wait_file2(chan, vms, "vm-first"); 07787 } else if (vms->curmsg == vms->lastmsg) { 07788 res = wait_file2(chan, vms, "vm-message"); 07789 res = wait_file2(chan, vms, "vm-last"); 07790 } else { 07791 res = wait_file2(chan, vms, "vm-message"); 07792 res = wait_file2(chan, vms, "vm-number"); 07793 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07794 } 07795 } else { 07796 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07797 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07798 } else { /* DEFAULT syntax */ 07799 res = wait_file2(chan, vms, "vm-message"); 07800 } 07801 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07802 if (!res) { 07803 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07804 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07805 } 07806 } 07807 } 07808 } 07809 07810 if (!valid_config(msg_cfg)) { 07811 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07812 return 0; 07813 } 07814 07815 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07816 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07817 DISPOSE(vms->curdir, vms->curmsg); 07818 ast_config_destroy(msg_cfg); 07819 return 0; 07820 } 07821 07822 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07823 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07824 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07825 07826 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07827 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07828 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07829 if (!res) { 07830 res = play_message_category(chan, category); 07831 } 07832 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07833 res = play_message_datetime(chan, vmu, origtime, filename); 07834 } 07835 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07836 res = play_message_callerid(chan, vms, cid, context, 0); 07837 } 07838 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07839 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07840 } 07841 /* Allow pressing '1' to skip envelope / callerid */ 07842 if (res == '1') { 07843 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07844 res = 0; 07845 } 07846 ast_config_destroy(msg_cfg); 07847 07848 if (!res) { 07849 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07850 #ifdef IMAP_STORAGE 07851 ast_mutex_lock(&vms->lock); 07852 #endif 07853 vms->heard[vms->curmsg] = 1; 07854 #ifdef IMAP_STORAGE 07855 ast_mutex_unlock(&vms->lock); 07856 /*IMAP storage stores any prepended message from a forward 07857 * as a separate file from the rest of the message 07858 */ 07859 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07860 wait_file(chan, vms, vms->introfn); 07861 } 07862 #endif 07863 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07864 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07865 res = 0; 07866 } 07867 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07868 } 07869 DISPOSE(vms->curdir, vms->curmsg); 07870 return res; 07871 }
| static int play_message_callerid | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | cid, | |||
| const char * | context, | |||
| int | callback | |||
| ) | [static] |
Definition at line 7598 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().
07599 { 07600 int res = 0; 07601 int i; 07602 char *callerid, *name; 07603 char prefile[PATH_MAX] = ""; 07604 07605 07606 /* If voicemail cid is not enabled, or we didn't get cid or context from 07607 * the attribute file, leave now. 07608 * 07609 * TODO Still need to change this so that if this function is called by the 07610 * message envelope (and someone is explicitly requesting to hear the CID), 07611 * it does not check to see if CID is enabled in the config file. 07612 */ 07613 if ((cid == NULL)||(context == NULL)) 07614 return res; 07615 07616 /* Strip off caller ID number from name */ 07617 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07618 ast_callerid_parse(cid, &name, &callerid); 07619 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07620 /* Check for internal contexts and only */ 07621 /* say extension when the call didn't come from an internal context in the list */ 07622 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07623 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07624 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07625 break; 07626 } 07627 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07628 if (!res) { 07629 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07630 if (!ast_strlen_zero(prefile)) { 07631 /* See if we can find a recorded name for this person instead of their extension number */ 07632 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07633 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07634 if (!callback) 07635 res = wait_file2(chan, vms, "vm-from"); 07636 res = ast_stream_and_wait(chan, prefile, ""); 07637 } else { 07638 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07639 /* Say "from extension" as one saying to sound smoother */ 07640 if (!callback) 07641 res = wait_file2(chan, vms, "vm-from-extension"); 07642 res = ast_say_digit_str(chan, callerid, "", chan->language); 07643 } 07644 } 07645 } 07646 } else if (!res) { 07647 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07648 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07649 if (!callback) 07650 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07651 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07652 } 07653 } else { 07654 /* Number unknown */ 07655 ast_debug(1, "VM-CID: From an unknown number\n"); 07656 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07657 res = wait_file2(chan, vms, "vm-unknown-caller"); 07658 } 07659 return res; 07660 }
| static int play_message_category | ( | struct ast_channel * | chan, | |
| const char * | category | |||
| ) | [static] |
Definition at line 7509 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
07510 { 07511 int res = 0; 07512 07513 if (!ast_strlen_zero(category)) 07514 res = ast_play_and_wait(chan, category); 07515 07516 if (res) { 07517 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07518 res = 0; 07519 } 07520 07521 return res; 07522 }
| static int play_message_datetime | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| const char * | origtime, | |||
| const char * | filename | |||
| ) | [static] |
Definition at line 7524 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().
07525 { 07526 int res = 0; 07527 struct vm_zone *the_zone = NULL; 07528 time_t t; 07529 07530 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07531 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07532 return 0; 07533 } 07534 07535 /* Does this user have a timezone specified? */ 07536 if (!ast_strlen_zero(vmu->zonetag)) { 07537 /* Find the zone in the list */ 07538 struct vm_zone *z; 07539 AST_LIST_LOCK(&zones); 07540 AST_LIST_TRAVERSE(&zones, z, list) { 07541 if (!strcmp(z->name, vmu->zonetag)) { 07542 the_zone = z; 07543 break; 07544 } 07545 } 07546 AST_LIST_UNLOCK(&zones); 07547 } 07548 07549 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07550 #if 0 07551 /* Set the DIFF_* variables */ 07552 ast_localtime(&t, &time_now, NULL); 07553 tv_now = ast_tvnow(); 07554 ast_localtime(&tv_now, &time_then, NULL); 07555 07556 /* Day difference */ 07557 if (time_now.tm_year == time_then.tm_year) 07558 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07559 else 07560 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07561 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07562 07563 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07564 #endif 07565 if (the_zone) { 07566 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07567 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07568 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07569 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07570 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07571 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07572 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); 07573 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07574 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07575 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07576 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07577 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07578 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07579 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07580 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); 07581 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07582 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07583 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07584 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07585 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07586 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); 07587 } else { 07588 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07589 } 07590 #if 0 07591 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07592 #endif 07593 return res; 07594 }
| static int play_message_duration | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| const char * | duration, | |||
| int | minduration | |||
| ) | [static] |
Definition at line 7662 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().
07663 { 07664 int res = 0; 07665 int durationm; 07666 int durations; 07667 /* Verify that we have a duration for the message */ 07668 if (duration == NULL) 07669 return res; 07670 07671 /* Convert from seconds to minutes */ 07672 durations = atoi(duration); 07673 durationm = (durations / 60); 07674 07675 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07676 07677 if ((!res) && (durationm >= minduration)) { 07678 res = wait_file2(chan, vms, "vm-duration"); 07679 07680 /* POLISH syntax */ 07681 if (!strncasecmp(chan->language, "pl", 2)) { 07682 div_t num = div(durationm, 10); 07683 07684 if (durationm == 1) { 07685 res = ast_play_and_wait(chan, "digits/1z"); 07686 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07687 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07688 if (num.rem == 2) { 07689 if (!num.quot) { 07690 res = ast_play_and_wait(chan, "digits/2-ie"); 07691 } else { 07692 res = say_and_wait(chan, durationm - 2 , chan->language); 07693 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07694 } 07695 } else { 07696 res = say_and_wait(chan, durationm, chan->language); 07697 } 07698 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07699 } else { 07700 res = say_and_wait(chan, durationm, chan->language); 07701 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07702 } 07703 /* DEFAULT syntax */ 07704 } else { 07705 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07706 res = wait_file2(chan, vms, "vm-minutes"); 07707 } 07708 } 07709 return res; 07710 }
| 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 13463 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().
13466 { 13467 /* Record message & let caller review or re-record it, or set options if applicable */ 13468 int res = 0; 13469 int cmd = 0; 13470 int max_attempts = 3; 13471 int attempts = 0; 13472 int recorded = 0; 13473 int msg_exists = 0; 13474 signed char zero_gain = 0; 13475 char tempfile[PATH_MAX]; 13476 char *acceptdtmf = "#"; 13477 char *canceldtmf = ""; 13478 int canceleddtmf = 0; 13479 13480 /* Note that urgent and private are for flagging messages as such in the future */ 13481 13482 /* barf if no pointer passed to store duration in */ 13483 if (duration == NULL) { 13484 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13485 return -1; 13486 } 13487 13488 if (!outsidecaller) 13489 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13490 else 13491 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13492 13493 cmd = '3'; /* Want to start by recording */ 13494 13495 while ((cmd >= 0) && (cmd != 't')) { 13496 switch (cmd) { 13497 case '1': 13498 if (!msg_exists) { 13499 /* In this case, 1 is to record a message */ 13500 cmd = '3'; 13501 break; 13502 } else { 13503 /* Otherwise 1 is to save the existing message */ 13504 ast_verb(3, "Saving message as is\n"); 13505 if (!outsidecaller) 13506 ast_filerename(tempfile, recordfile, NULL); 13507 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13508 if (!outsidecaller) { 13509 /* Saves to IMAP server only if imapgreeting=yes */ 13510 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13511 DISPOSE(recordfile, -1); 13512 } 13513 cmd = 't'; 13514 return res; 13515 } 13516 case '2': 13517 /* Review */ 13518 ast_verb(3, "Reviewing the message\n"); 13519 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13520 break; 13521 case '3': 13522 msg_exists = 0; 13523 /* Record */ 13524 if (recorded == 1) 13525 ast_verb(3, "Re-recording the message\n"); 13526 else 13527 ast_verb(3, "Recording the message\n"); 13528 13529 if (recorded && outsidecaller) { 13530 cmd = ast_play_and_wait(chan, INTRO); 13531 cmd = ast_play_and_wait(chan, "beep"); 13532 } 13533 recorded = 1; 13534 /* 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 */ 13535 if (record_gain) 13536 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13537 if (ast_test_flag(vmu, VM_OPERATOR)) 13538 canceldtmf = "0"; 13539 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13540 if (strchr(canceldtmf, cmd)) { 13541 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13542 canceleddtmf = 1; 13543 } 13544 if (record_gain) 13545 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13546 if (cmd == -1) { 13547 /* User has hung up, no options to give */ 13548 if (!outsidecaller) { 13549 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13550 ast_filedelete(tempfile, NULL); 13551 } 13552 return cmd; 13553 } 13554 if (cmd == '0') { 13555 break; 13556 } else if (cmd == '*') { 13557 break; 13558 #if 0 13559 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13560 /* Message is too short */ 13561 ast_verb(3, "Message too short\n"); 13562 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13563 cmd = ast_filedelete(tempfile, NULL); 13564 break; 13565 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13566 /* Message is all silence */ 13567 ast_verb(3, "Nothing recorded\n"); 13568 cmd = ast_filedelete(tempfile, NULL); 13569 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13570 if (!cmd) 13571 cmd = ast_play_and_wait(chan, "vm-speakup"); 13572 break; 13573 #endif 13574 } else { 13575 /* If all is well, a message exists */ 13576 msg_exists = 1; 13577 cmd = 0; 13578 } 13579 break; 13580 case '4': 13581 if (outsidecaller) { /* only mark vm messages */ 13582 /* Mark Urgent */ 13583 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13584 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13585 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13586 strcpy(flag, "Urgent"); 13587 } else if (flag) { 13588 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13589 res = ast_play_and_wait(chan, "vm-marked-nonurgent"); 13590 strcpy(flag, ""); 13591 } else { 13592 ast_play_and_wait(chan, "vm-sorry"); 13593 } 13594 cmd = 0; 13595 } else { 13596 cmd = ast_play_and_wait(chan, "vm-sorry"); 13597 } 13598 break; 13599 case '5': 13600 case '6': 13601 case '7': 13602 case '8': 13603 case '9': 13604 case '*': 13605 case '#': 13606 cmd = ast_play_and_wait(chan, "vm-sorry"); 13607 break; 13608 #if 0 13609 /* XXX Commented out for the moment because of the dangers of deleting 13610 a message while recording (can put the message numbers out of sync) */ 13611 case '*': 13612 /* Cancel recording, delete message, offer to take another message*/ 13613 cmd = ast_play_and_wait(chan, "vm-deleted"); 13614 cmd = ast_filedelete(tempfile, NULL); 13615 if (outsidecaller) { 13616 res = vm_exec(chan, NULL); 13617 return res; 13618 } 13619 else 13620 return 1; 13621 #endif 13622 case '0': 13623 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13624 cmd = ast_play_and_wait(chan, "vm-sorry"); 13625 break; 13626 } 13627 if (msg_exists || recorded) { 13628 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13629 if (!cmd) 13630 cmd = ast_waitfordigit(chan, 3000); 13631 if (cmd == '1') { 13632 ast_filerename(tempfile, recordfile, NULL); 13633 ast_play_and_wait(chan, "vm-msgsaved"); 13634 cmd = '0'; 13635 } else if (cmd == '4') { 13636 if (flag) { 13637 ast_play_and_wait(chan, "vm-marked-urgent"); 13638 strcpy(flag, "Urgent"); 13639 } 13640 ast_play_and_wait(chan, "vm-msgsaved"); 13641 cmd = '0'; 13642 } else { 13643 ast_play_and_wait(chan, "vm-deleted"); 13644 DELETE(tempfile, -1, tempfile, vmu); 13645 cmd = '0'; 13646 } 13647 } 13648 return cmd; 13649 default: 13650 /* If the caller is an ouside caller, and the review option is enabled, 13651 allow them to review the message, but let the owner of the box review 13652 their OGM's */ 13653 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13654 return cmd; 13655 if (msg_exists) { 13656 cmd = ast_play_and_wait(chan, "vm-review"); 13657 if (!cmd && outsidecaller) { 13658 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13659 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13660 } else if (flag) { 13661 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13662 } 13663 } 13664 } else { 13665 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13666 if (!cmd) 13667 cmd = ast_waitfordigit(chan, 600); 13668 } 13669 13670 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13671 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13672 if (!cmd) 13673 cmd = ast_waitfordigit(chan, 600); 13674 } 13675 #if 0 13676 if (!cmd) 13677 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13678 #endif 13679 if (!cmd) 13680 cmd = ast_waitfordigit(chan, 6000); 13681 if (!cmd) { 13682 attempts++; 13683 } 13684 if (attempts > max_attempts) { 13685 cmd = 't'; 13686 } 13687 } 13688 } 13689 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13690 /* Hang up or timeout, so delete the recording. */ 13691 ast_filedelete(tempfile, NULL); 13692 } 13693 13694 if (cmd != 't' && outsidecaller) 13695 ast_play_and_wait(chan, "vm-goodbye"); 13696 13697 return cmd; 13698 }
| static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11473 of file app_voicemail.c.
References inboxcount2(), queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11474 { 11475 int new = 0, old = 0, urgent = 0; 11476 11477 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11478 11479 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11480 mwi_sub->old_urgent = urgent; 11481 mwi_sub->old_new = new; 11482 mwi_sub->old_old = old; 11483 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11484 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11485 } 11486 }
| static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11488 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().
11489 { 11490 struct mwi_sub *mwi_sub; 11491 11492 AST_RWLIST_RDLOCK(&mwi_subs); 11493 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11494 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11495 poll_subscribed_mailbox(mwi_sub); 11496 } 11497 } 11498 AST_RWLIST_UNLOCK(&mwi_subs); 11499 }
| 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 12579 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().
12579 { 12580 struct ast_config *pwconf; 12581 struct ast_flags config_flags = { 0 }; 12582 12583 pwconf = ast_config_load(secretfn, config_flags); 12584 if (valid_config(pwconf)) { 12585 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12586 if (val) { 12587 ast_copy_string(password, val, passwordlen); 12588 ast_config_destroy(pwconf); 12589 return; 12590 } 12591 ast_config_destroy(pwconf); 12592 } 12593 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12594 }
| static int reload | ( | void | ) | [static] |
Definition at line 13110 of file app_voicemail.c.
References load_config().
13111 { 13112 return load_config(1); 13113 }
| 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 12565 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().
12566 { 12567 int res = -1; 12568 char dir[PATH_MAX]; 12569 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12570 ast_debug(2, "About to try retrieving name file %s\n", dir); 12571 RETRIEVE(dir, -1, mailbox, context); 12572 if (ast_fileexists(dir, NULL, NULL)) { 12573 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12574 } 12575 DISPOSE(dir, -1); 12576 return res; 12577 }
| 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 %u\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 11130 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().
11131 { 11132 struct ast_config *cfg; 11133 const char *cat = NULL; 11134 11135 if (!(cfg = ast_load_realtime_multientry("voicemail", 11136 "context", context, SENTINEL))) { 11137 return CLI_FAILURE; 11138 } 11139 11140 ast_cli(fd, 11141 "\n" 11142 "=============================================================\n" 11143 "=== Configured Voicemail Users ==============================\n" 11144 "=============================================================\n" 11145 "===\n"); 11146 11147 while ((cat = ast_category_browse(cfg, cat))) { 11148 struct ast_variable *var = NULL; 11149 ast_cli(fd, 11150 "=== Mailbox ...\n" 11151 "===\n"); 11152 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11153 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11154 ast_cli(fd, 11155 "===\n" 11156 "=== ---------------------------------------------------------\n" 11157 "===\n"); 11158 } 11159 11160 ast_cli(fd, 11161 "=============================================================\n" 11162 "\n"); 11163 11164 ast_config_destroy(cfg); 11165 11166 return CLI_SUCCESS; 11167 }
| static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11635 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().
11636 { 11637 int errcode; 11638 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11639 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11640 AST_EVENT_IE_END); 11641 11642 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11643 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11644 AST_EVENT_IE_END); 11645 11646 if (mwi_sub_sub) 11647 ast_event_report_subs(mwi_sub_sub); 11648 11649 poll_thread_run = 1; 11650 11651 if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) { 11652 ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode)); 11653 } 11654 }
| static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11656 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().
11657 { 11658 poll_thread_run = 0; 11659 11660 if (mwi_sub_sub) { 11661 ast_event_unsubscribe(mwi_sub_sub); 11662 mwi_sub_sub = NULL; 11663 } 11664 11665 if (mwi_unsub_sub) { 11666 ast_event_unsubscribe(mwi_unsub_sub); 11667 mwi_unsub_sub = NULL; 11668 } 11669 11670 ast_mutex_lock(&poll_lock); 11671 ast_cond_signal(&poll_cond); 11672 ast_mutex_unlock(&poll_lock); 11673 11674 pthread_join(poll_thread, NULL); 11675 11676 poll_thread = AST_PTHREADT_NULL; 11677 }
| 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 11802 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().
11803 { 11804 char *current; 11805 11806 /* Add 16 for fudge factor */ 11807 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11808 11809 ast_str_reset(str); 11810 11811 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11812 for (current = (char *) value; *current; current++) { 11813 if (*current == '\\') { 11814 current++; 11815 if (!*current) { 11816 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11817 break; 11818 } 11819 switch (*current) { 11820 case '\\': 11821 ast_str_append(&str, 0, "\\"); 11822 break; 11823 case 'r': 11824 ast_str_append(&str, 0, "\r"); 11825 break; 11826 case 'n': 11827 #ifdef IMAP_STORAGE 11828 if (!str->used || str->str[str->used - 1] != '\r') { 11829 ast_str_append(&str, 0, "\r"); 11830 } 11831 #endif 11832 ast_str_append(&str, 0, "\n"); 11833 break; 11834 case 't': 11835 ast_str_append(&str, 0, "\t"); 11836 break; 11837 default: 11838 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11839 break; 11840 } 11841 } else { 11842 ast_str_append(&str, 0, "%c", *current); 11843 } 11844 } 11845 11846 return ast_str_buffer(str); 11847 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 13115 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().
13116 { 13117 int res; 13118 13119 res = ast_unregister_application(app); 13120 res |= ast_unregister_application(app2); 13121 res |= ast_unregister_application(app3); 13122 res |= ast_unregister_application(app4); 13123 res |= ast_unregister_application(sayname_app); 13124 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13125 res |= ast_manager_unregister("VoicemailUsersList"); 13126 res |= ast_data_unregister(NULL); 13127 #ifdef TEST_FRAMEWORK 13128 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13129 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13130 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13131 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13132 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13133 #endif 13134 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13135 ast_uninstall_vm_functions(); 13136 ao2_ref(inprocess_container, -1); 13137 13138 if (poll_thread != AST_PTHREADT_NULL) 13139 stop_poll_thread(); 13140 13141 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13142 ast_unload_realtime("voicemail"); 13143 ast_unload_realtime("voicemail_data"); 13144 13145 free_vm_users(); 13146 free_vm_zones(); 13147 return res; 13148 }
| 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 9810 of file app_voicemail.c.
References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_verb, ast_waitstream(), ast_channel::caller, ast_channel::context, find_user(), ast_party_caller::id, ast_party_id::number, ast_vm_user::password, S_COR, ast_party_number::str, ast_party_number::valid, and vm_password.
Referenced by vm_execmain(), and vmauthenticate().
09813 { 09814 int useadsi = 0, valid = 0, logretries = 0; 09815 char password[AST_MAX_EXTENSION]="", *passptr; 09816 struct ast_vm_user vmus, *vmu = NULL; 09817 09818 /* If ADSI is supported, setup login screen */ 09819 adsi_begin(chan, &useadsi); 09820 if (!skipuser && useadsi) 09821 adsi_login(chan); 09822 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09823 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09824 return -1; 09825 } 09826 09827 /* Authenticate them and get their mailbox/password */ 09828 09829 while (!valid && (logretries < max_logins)) { 09830 /* Prompt for, and read in the username */ 09831 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09832 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09833 return -1; 09834 } 09835 if (ast_strlen_zero(mailbox)) { 09836 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09837 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09838 } else { 09839 ast_verb(3, "Username not entered\n"); 09840 return -1; 09841 } 09842 } else if (mailbox[0] == '*') { 09843 /* user entered '*' */ 09844 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09845 if (ast_exists_extension(chan, chan->context, "a", 1, 09846 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09847 return -1; 09848 } 09849 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09850 mailbox[0] = '\0'; 09851 } 09852 09853 if (useadsi) 09854 adsi_password(chan); 09855 09856 if (!ast_strlen_zero(prefix)) { 09857 char fullusername[80] = ""; 09858 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09859 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09860 ast_copy_string(mailbox, fullusername, mailbox_size); 09861 } 09862 09863 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09864 vmu = find_user(&vmus, context, mailbox); 09865 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09866 /* saved password is blank, so don't bother asking */ 09867 password[0] = '\0'; 09868 } else { 09869 if (ast_streamfile(chan, vm_password, chan->language)) { 09870 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09871 return -1; 09872 } 09873 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09874 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09875 return -1; 09876 } else if (password[0] == '*') { 09877 /* user entered '*' */ 09878 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09879 if (ast_exists_extension(chan, chan->context, "a", 1, 09880 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09881 mailbox[0] = '*'; 09882 return -1; 09883 } 09884 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09885 mailbox[0] = '\0'; 09886 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09887 vmu = NULL; 09888 } 09889 } 09890 09891 if (vmu) { 09892 passptr = vmu->password; 09893 if (passptr[0] == '-') passptr++; 09894 } 09895 if (vmu && !strcmp(passptr, password)) 09896 valid++; 09897 else { 09898 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09899 if (!ast_strlen_zero(prefix)) 09900 mailbox[0] = '\0'; 09901 } 09902 logretries++; 09903 if (!valid) { 09904 if (skipuser || logretries >= max_logins) { 09905 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09906 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09907 return -1; 09908 } 09909 } else { 09910 if (useadsi) 09911 adsi_login(chan); 09912 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09913 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09914 return -1; 09915 } 09916 } 09917 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09918 return -1; 09919 } 09920 } 09921 if (!valid && (logretries >= max_logins)) { 09922 ast_stopstream(chan); 09923 ast_play_and_wait(chan, "vm-goodbye"); 09924 return -1; 09925 } 09926 if (vmu && !skipuser) { 09927 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09928 } 09929 return 0; 09930 }
| static int vm_box_exists | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 11025 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().
11026 { 11027 struct ast_vm_user svm; 11028 char *context, *box; 11029 AST_DECLARE_APP_ARGS(args, 11030 AST_APP_ARG(mbox); 11031 AST_APP_ARG(options); 11032 ); 11033 static int dep_warning = 0; 11034 11035 if (ast_strlen_zero(data)) { 11036 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 11037 return -1; 11038 } 11039 11040 if (!dep_warning) { 11041 dep_warning = 1; 11042 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 11043 } 11044 11045 box = ast_strdupa(data); 11046 11047 AST_STANDARD_APP_ARGS(args, box); 11048 11049 if (args.options) { 11050 } 11051 11052 if ((context = strchr(args.mbox, '@'))) { 11053 *context = '\0'; 11054 context++; 11055 } 11056 11057 if (find_user(&svm, context, args.mbox)) { 11058 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11059 } else 11060 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11061 11062 return 0; 11063 }
| 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 9789 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().
09790 { 09791 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09792 return vm_browse_messages_es(chan, vms, vmu); 09793 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09794 return vm_browse_messages_gr(chan, vms, vmu); 09795 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09796 return vm_browse_messages_he(chan, vms, vmu); 09797 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09798 return vm_browse_messages_it(chan, vms, vmu); 09799 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09800 return vm_browse_messages_pt(chan, vms, vmu); 09801 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09802 return vm_browse_messages_vi(chan, vms, vmu); 09803 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09804 return vm_browse_messages_zh(chan, vms, vmu); 09805 } else { /* Default to English syntax */ 09806 return vm_browse_messages_en(chan, vms, vmu); 09807 } 09808 }
| 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 9628 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().
09629 { 09630 int cmd = 0; 09631 09632 if (vms->lastmsg > -1) { 09633 cmd = play_message(chan, vmu, vms); 09634 } else { 09635 cmd = ast_play_and_wait(chan, "vm-youhave"); 09636 if (!cmd) 09637 cmd = ast_play_and_wait(chan, "vm-no"); 09638 if (!cmd) { 09639 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09640 cmd = ast_play_and_wait(chan, vms->fn); 09641 } 09642 if (!cmd) 09643 cmd = ast_play_and_wait(chan, "vm-messages"); 09644 } 09645 return cmd; 09646 }
| 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 9682 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().
09683 { 09684 int cmd; 09685 09686 if (vms->lastmsg > -1) { 09687 cmd = play_message(chan, vmu, vms); 09688 } else { 09689 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09690 if (!cmd) 09691 cmd = ast_play_and_wait(chan, "vm-messages"); 09692 if (!cmd) { 09693 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09694 cmd = ast_play_and_wait(chan, vms->fn); 09695 } 09696 } 09697 return cmd; 09698 }
| 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 9576 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().
09577 { 09578 int cmd = 0; 09579 09580 if (vms->lastmsg > -1) { 09581 cmd = play_message(chan, vmu, vms); 09582 } else { 09583 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09584 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09585 if (!cmd) { 09586 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09587 cmd = ast_play_and_wait(chan, vms->fn); 09588 } 09589 if (!cmd) 09590 cmd = ast_play_and_wait(chan, "vm-messages"); 09591 } else { 09592 if (!cmd) 09593 cmd = ast_play_and_wait(chan, "vm-messages"); 09594 if (!cmd) { 09595 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09596 cmd = ast_play_and_wait(chan, vms->fn); 09597 } 09598 } 09599 } 09600 return cmd; 09601 }
| static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| struct ast_vm_user * | vmu | |||
| ) | [static] |
Definition at line 9604 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09605 { 09606 int cmd = 0; 09607 09608 if (vms->lastmsg > -1) { 09609 cmd = play_message(chan, vmu, vms); 09610 } else { 09611 if (!strcasecmp(vms->fn, "INBOX")) { 09612 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09613 } else { 09614 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09615 } 09616 } 09617 return cmd; 09618 }
| 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 9656 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().
09657 { 09658 int cmd; 09659 09660 if (vms->lastmsg > -1) { 09661 cmd = play_message(chan, vmu, vms); 09662 } else { 09663 cmd = ast_play_and_wait(chan, "vm-no"); 09664 if (!cmd) 09665 cmd = ast_play_and_wait(chan, "vm-message"); 09666 if (!cmd) { 09667 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09668 cmd = ast_play_and_wait(chan, vms->fn); 09669 } 09670 } 09671 return cmd; 09672 }
| 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 9708 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().
09709 { 09710 int cmd; 09711 09712 if (vms->lastmsg > -1) { 09713 cmd = play_message(chan, vmu, vms); 09714 } else { 09715 cmd = ast_play_and_wait(chan, "vm-no"); 09716 if (!cmd) { 09717 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09718 cmd = ast_play_and_wait(chan, vms->fn); 09719 } 09720 if (!cmd) 09721 cmd = ast_play_and_wait(chan, "vm-messages"); 09722 } 09723 return cmd; 09724 }
| 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 9762 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().
09763 { 09764 int cmd = 0; 09765 09766 if (vms->lastmsg > -1) { 09767 cmd = play_message(chan, vmu, vms); 09768 } else { 09769 cmd = ast_play_and_wait(chan, "vm-no"); 09770 if (!cmd) { 09771 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09772 cmd = ast_play_and_wait(chan, vms->fn); 09773 } 09774 } 09775 return cmd; 09776 }
| 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 9734 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().
09735 { 09736 int cmd; 09737 09738 if (vms->lastmsg > -1) { 09739 cmd = play_message(chan, vmu, vms); 09740 } else { 09741 cmd = ast_play_and_wait(chan, "vm-you"); 09742 if (!cmd) 09743 cmd = ast_play_and_wait(chan, "vm-haveno"); 09744 if (!cmd) 09745 cmd = ast_play_and_wait(chan, "vm-messages"); 09746 if (!cmd) { 09747 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09748 cmd = ast_play_and_wait(chan, vms->fn); 09749 } 09750 } 09751 return cmd; 09752 }
| 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 10684 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().
10685 { 10686 int res = 0; 10687 char *tmp; 10688 struct leave_vm_options leave_options; 10689 struct ast_flags flags = { 0 }; 10690 char *opts[OPT_ARG_ARRAY_SIZE]; 10691 AST_DECLARE_APP_ARGS(args, 10692 AST_APP_ARG(argv0); 10693 AST_APP_ARG(argv1); 10694 ); 10695 10696 memset(&leave_options, 0, sizeof(leave_options)); 10697 10698 if (chan->_state != AST_STATE_UP) 10699 ast_answer(chan); 10700 10701 if (!ast_strlen_zero(data)) { 10702 tmp = ast_strdupa(data); 10703 AST_STANDARD_APP_ARGS(args, tmp); 10704 if (args.argc == 2) { 10705 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10706 return -1; 10707 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10708 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10709 int gain; 10710 10711 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10712 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10713 return -1; 10714 } else { 10715 leave_options.record_gain = (signed char) gain; 10716 } 10717 } 10718 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10719 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10720 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10721 } 10722 } 10723 } else { 10724 char temp[256]; 10725 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10726 if (res < 0) 10727 return res; 10728 if (ast_strlen_zero(temp)) 10729 return 0; 10730 args.argv0 = ast_strdupa(temp); 10731 } 10732 10733 res = leave_voicemail(chan, args.argv0, &leave_options); 10734 if (res == 't') { 10735 ast_play_and_wait(chan, "vm-goodbye"); 10736 res = 0; 10737 } 10738 10739 if (res == OPERATOR_EXIT) { 10740 res = 0; 10741 } 10742 10743 if (res == ERROR_LOCK_PATH) { 10744 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10745 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10746 res = 0; 10747 } 10748 10749 return res; 10750 }
| static int vm_execmain | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 9932 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().
09933 { 09934 /* XXX This is, admittedly, some pretty horrendous code. For some 09935 reason it just seemed a lot easier to do with GOTO's. I feel 09936 like I'm back in my GWBASIC days. XXX */ 09937 int res = -1; 09938 int cmd = 0; 09939 int valid = 0; 09940 char prefixstr[80] =""; 09941 char ext_context[256]=""; 09942 int box; 09943 int useadsi = 0; 09944 int skipuser = 0; 09945 struct vm_state vms; 09946 struct ast_vm_user *vmu = NULL, vmus; 09947 char *context = NULL; 09948 int silentexit = 0; 09949 struct ast_flags flags = { 0 }; 09950 signed char record_gain = 0; 09951 int play_auto = 0; 09952 int play_folder = 0; 09953 int in_urgent = 0; 09954 #ifdef IMAP_STORAGE 09955 int deleted = 0; 09956 #endif 09957 09958 /* Add the vm_state to the active list and keep it active */ 09959 memset(&vms, 0, sizeof(vms)); 09960 09961 vms.lastmsg = -1; 09962 09963 memset(&vmus, 0, sizeof(vmus)); 09964 09965 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09966 if (chan->_state != AST_STATE_UP) { 09967 ast_debug(1, "Before ast_answer\n"); 09968 ast_answer(chan); 09969 } 09970 09971 if (!ast_strlen_zero(data)) { 09972 char *opts[OPT_ARG_ARRAY_SIZE]; 09973 char *parse; 09974 AST_DECLARE_APP_ARGS(args, 09975 AST_APP_ARG(argv0); 09976 AST_APP_ARG(argv1); 09977 ); 09978 09979 parse = ast_strdupa(data); 09980 09981 AST_STANDARD_APP_ARGS(args, parse); 09982 09983 if (args.argc == 2) { 09984 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09985 return -1; 09986 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09987 int gain; 09988 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09989 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09990 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09991 return -1; 09992 } else { 09993 record_gain = (signed char) gain; 09994 } 09995 } else { 09996 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09997 } 09998 } 09999 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 10000 play_auto = 1; 10001 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 10002 /* See if it is a folder name first */ 10003 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 10004 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 10005 play_folder = -1; 10006 } 10007 } else { 10008 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 10009 } 10010 } else { 10011 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 10012 } 10013 if (play_folder > 9 || play_folder < 0) { 10014 ast_log(AST_LOG_WARNING, 10015 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 10016 opts[OPT_ARG_PLAYFOLDER]); 10017 play_folder = 0; 10018 } 10019 } 10020 } else { 10021 /* old style options parsing */ 10022 while (*(args.argv0)) { 10023 if (*(args.argv0) == 's') 10024 ast_set_flag(&flags, OPT_SILENT); 10025 else if (*(args.argv0) == 'p') 10026 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 10027 else 10028 break; 10029 (args.argv0)++; 10030 } 10031 10032 } 10033 10034 valid = ast_test_flag(&flags, OPT_SILENT); 10035 10036 if ((context = strchr(args.argv0, '@'))) 10037 *context++ = '\0'; 10038 10039 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 10040 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 10041 else 10042 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 10043 10044 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 10045 skipuser++; 10046 else 10047 valid = 0; 10048 } 10049 10050 if (!valid) 10051 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 10052 10053 ast_debug(1, "After vm_authenticate\n"); 10054 10055 if (vms.username[0] == '*') { 10056 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 10057 10058 /* user entered '*' */ 10059 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10060 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 10061 res = 0; /* prevent hangup */ 10062 goto out; 10063 } 10064 } 10065 10066 if (!res) { 10067 valid = 1; 10068 if (!skipuser) 10069 vmu = &vmus; 10070 } else { 10071 res = 0; 10072 } 10073 10074 /* If ADSI is supported, setup login screen */ 10075 adsi_begin(chan, &useadsi); 10076 10077 ast_test_suite_assert(valid); 10078 if (!valid) { 10079 goto out; 10080 } 10081 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10082 10083 #ifdef IMAP_STORAGE 10084 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10085 pthread_setspecific(ts_vmstate.key, &vms); 10086 10087 vms.interactive = 1; 10088 vms.updated = 1; 10089 if (vmu) 10090 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10091 vmstate_insert(&vms); 10092 init_vm_state(&vms); 10093 #endif 10094 10095 /* Set language from config to override channel language */ 10096 if (!ast_strlen_zero(vmu->language)) 10097 ast_string_field_set(chan, language, vmu->language); 10098 10099 /* Retrieve urgent, old and new message counts */ 10100 ast_debug(1, "Before open_mailbox\n"); 10101 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10102 if (res < 0) 10103 goto out; 10104 vms.oldmessages = vms.lastmsg + 1; 10105 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10106 /* check INBOX */ 10107 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10108 if (res < 0) 10109 goto out; 10110 vms.newmessages = vms.lastmsg + 1; 10111 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10112 /* Start in Urgent */ 10113 in_urgent = 1; 10114 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10115 if (res < 0) 10116 goto out; 10117 vms.urgentmessages = vms.lastmsg + 1; 10118 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10119 10120 /* Select proper mailbox FIRST!! */ 10121 if (play_auto) { 10122 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10123 if (vms.urgentmessages) { 10124 in_urgent = 1; 10125 res = open_mailbox(&vms, vmu, 11); 10126 } else { 10127 in_urgent = 0; 10128 res = open_mailbox(&vms, vmu, play_folder); 10129 } 10130 if (res < 0) 10131 goto out; 10132 10133 /* If there are no new messages, inform the user and hangup */ 10134 if (vms.lastmsg == -1) { 10135 in_urgent = 0; 10136 cmd = vm_browse_messages(chan, &vms, vmu); 10137 res = 0; 10138 goto out; 10139 } 10140 } else { 10141 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10142 /* If we only have old messages start here */ 10143 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10144 in_urgent = 0; 10145 play_folder = 1; 10146 if (res < 0) 10147 goto out; 10148 } else if (!vms.urgentmessages && vms.newmessages) { 10149 /* If we have new messages but none are urgent */ 10150 in_urgent = 0; 10151 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10152 if (res < 0) 10153 goto out; 10154 } 10155 } 10156 10157 if (useadsi) 10158 adsi_status(chan, &vms); 10159 res = 0; 10160 10161 /* Check to see if this is a new user */ 10162 if (!strcasecmp(vmu->mailbox, vmu->password) && 10163 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10164 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10165 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10166 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10167 if ((cmd == 't') || (cmd == '#')) { 10168 /* Timeout */ 10169 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10170 res = 0; 10171 goto out; 10172 } else if (cmd < 0) { 10173 /* Hangup */ 10174 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10175 res = -1; 10176 goto out; 10177 } 10178 } 10179 #ifdef IMAP_STORAGE 10180 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10181 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10182 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10183 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10184 } 10185 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10186 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10187 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10188 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10189 } 10190 #endif 10191 10192 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10193 if (play_auto) { 10194 cmd = '1'; 10195 } else { 10196 cmd = vm_intro(chan, vmu, &vms); 10197 } 10198 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10199 10200 vms.repeats = 0; 10201 vms.starting = 1; 10202 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10203 /* Run main menu */ 10204 switch (cmd) { 10205 case '1': /* First message */ 10206 vms.curmsg = 0; 10207 /* Fall through */ 10208 case '5': /* Play current message */ 10209 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10210 cmd = vm_browse_messages(chan, &vms, vmu); 10211 break; 10212 case '2': /* Change folders */ 10213 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10214 if (useadsi) 10215 adsi_folders(chan, 0, "Change to folder..."); 10216 10217 cmd = get_folder2(chan, "vm-changeto", 0); 10218 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10219 if (cmd == '#') { 10220 cmd = 0; 10221 } else if (cmd > 0) { 10222 cmd = cmd - '0'; 10223 res = close_mailbox(&vms, vmu); 10224 if (res == ERROR_LOCK_PATH) 10225 goto out; 10226 /* If folder is not urgent, set in_urgent to zero! */ 10227 if (cmd != 11) in_urgent = 0; 10228 res = open_mailbox(&vms, vmu, cmd); 10229 if (res < 0) 10230 goto out; 10231 play_folder = cmd; 10232 cmd = 0; 10233 } 10234 if (useadsi) 10235 adsi_status2(chan, &vms); 10236 10237 if (!cmd) { 10238 cmd = vm_play_folder_name(chan, vms.vmbox); 10239 } 10240 10241 vms.starting = 1; 10242 vms.curmsg = 0; 10243 break; 10244 case '3': /* Advanced options */ 10245 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10246 cmd = 0; 10247 vms.repeats = 0; 10248 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10249 switch (cmd) { 10250 case '1': /* Reply */ 10251 if (vms.lastmsg > -1 && !vms.starting) { 10252 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10253 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10254 res = cmd; 10255 goto out; 10256 } 10257 } else { 10258 cmd = ast_play_and_wait(chan, "vm-sorry"); 10259 } 10260 cmd = 't'; 10261 break; 10262 case '2': /* Callback */ 10263 if (!vms.starting) 10264 ast_verb(3, "Callback Requested\n"); 10265 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10266 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10267 if (cmd == 9) { 10268 silentexit = 1; 10269 goto out; 10270 } else if (cmd == ERROR_LOCK_PATH) { 10271 res = cmd; 10272 goto out; 10273 } 10274 } else { 10275 cmd = ast_play_and_wait(chan, "vm-sorry"); 10276 } 10277 cmd = 't'; 10278 break; 10279 case '3': /* Envelope */ 10280 if (vms.lastmsg > -1 && !vms.starting) { 10281 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10282 if (cmd == ERROR_LOCK_PATH) { 10283 res = cmd; 10284 goto out; 10285 } 10286 } else { 10287 cmd = ast_play_and_wait(chan, "vm-sorry"); 10288 } 10289 cmd = 't'; 10290 break; 10291 case '4': /* Dialout */ 10292 if (!ast_strlen_zero(vmu->dialout)) { 10293 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10294 if (cmd == 9) { 10295 silentexit = 1; 10296 goto out; 10297 } 10298 } else { 10299 cmd = ast_play_and_wait(chan, "vm-sorry"); 10300 } 10301 cmd = 't'; 10302 break; 10303 10304 case '5': /* Leave VoiceMail */ 10305 if (ast_test_flag(vmu, VM_SVMAIL)) { 10306 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10307 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10308 res = cmd; 10309 goto out; 10310 } 10311 } else { 10312 cmd = ast_play_and_wait(chan, "vm-sorry"); 10313 } 10314 cmd = 't'; 10315 break; 10316 10317 case '*': /* Return to main menu */ 10318 cmd = 't'; 10319 break; 10320 10321 default: 10322 cmd = 0; 10323 if (!vms.starting) { 10324 cmd = ast_play_and_wait(chan, "vm-toreply"); 10325 } 10326 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10327 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10328 } 10329 if (!cmd && !vms.starting) { 10330 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10331 } 10332 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10333 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10334 } 10335 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10336 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10337 } 10338 if (!cmd) { 10339 cmd = ast_play_and_wait(chan, "vm-starmain"); 10340 } 10341 if (!cmd) { 10342 cmd = ast_waitfordigit(chan, 6000); 10343 } 10344 if (!cmd) { 10345 vms.repeats++; 10346 } 10347 if (vms.repeats > 3) { 10348 cmd = 't'; 10349 } 10350 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10351 } 10352 } 10353 if (cmd == 't') { 10354 cmd = 0; 10355 vms.repeats = 0; 10356 } 10357 break; 10358 case '4': /* Go to the previous message */ 10359 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10360 if (vms.curmsg > 0) { 10361 vms.curmsg--; 10362 cmd = play_message(chan, vmu, &vms); 10363 } else { 10364 /* Check if we were listening to new 10365 messages. If so, go to Urgent messages 10366 instead of saying "no more messages" 10367 */ 10368 if (in_urgent == 0 && vms.urgentmessages > 0) { 10369 /* Check for Urgent messages */ 10370 in_urgent = 1; 10371 res = close_mailbox(&vms, vmu); 10372 if (res == ERROR_LOCK_PATH) 10373 goto out; 10374 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10375 if (res < 0) 10376 goto out; 10377 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10378 vms.curmsg = vms.lastmsg; 10379 if (vms.lastmsg < 0) { 10380 cmd = ast_play_and_wait(chan, "vm-nomore"); 10381 } 10382 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10383 vms.curmsg = vms.lastmsg; 10384 cmd = play_message(chan, vmu, &vms); 10385 } else { 10386 cmd = ast_play_and_wait(chan, "vm-nomore"); 10387 } 10388 } 10389 break; 10390 case '6': /* Go to the next message */ 10391 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10392 if (vms.curmsg < vms.lastmsg) { 10393 vms.curmsg++; 10394 cmd = play_message(chan, vmu, &vms); 10395 } else { 10396 if (in_urgent && vms.newmessages > 0) { 10397 /* Check if we were listening to urgent 10398 * messages. If so, go to regular new messages 10399 * instead of saying "no more messages" 10400 */ 10401 in_urgent = 0; 10402 res = close_mailbox(&vms, vmu); 10403 if (res == ERROR_LOCK_PATH) 10404 goto out; 10405 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10406 if (res < 0) 10407 goto out; 10408 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10409 vms.curmsg = -1; 10410 if (vms.lastmsg < 0) { 10411 cmd = ast_play_and_wait(chan, "vm-nomore"); 10412 } 10413 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10414 vms.curmsg = 0; 10415 cmd = play_message(chan, vmu, &vms); 10416 } else { 10417 cmd = ast_play_and_wait(chan, "vm-nomore"); 10418 } 10419 } 10420 break; 10421 case '7': /* Delete the current message */ 10422 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10423 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10424 if (useadsi) 10425 adsi_delete(chan, &vms); 10426 if (vms.deleted[vms.curmsg]) { 10427 if (play_folder == 0) { 10428 if (in_urgent) { 10429 vms.urgentmessages--; 10430 } else { 10431 vms.newmessages--; 10432 } 10433 } 10434 else if (play_folder == 1) 10435 vms.oldmessages--; 10436 cmd = ast_play_and_wait(chan, "vm-deleted"); 10437 } else { 10438 if (play_folder == 0) { 10439 if (in_urgent) { 10440 vms.urgentmessages++; 10441 } else { 10442 vms.newmessages++; 10443 } 10444 } 10445 else if (play_folder == 1) 10446 vms.oldmessages++; 10447 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10448 } 10449 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10450 if (vms.curmsg < vms.lastmsg) { 10451 vms.curmsg++; 10452 cmd = play_message(chan, vmu, &vms); 10453 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10454 vms.curmsg = 0; 10455 cmd = play_message(chan, vmu, &vms); 10456 } else { 10457 /* Check if we were listening to urgent 10458 messages. If so, go to regular new messages 10459 instead of saying "no more messages" 10460 */ 10461 if (in_urgent == 1) { 10462 /* Check for new messages */ 10463 in_urgent = 0; 10464 res = close_mailbox(&vms, vmu); 10465 if (res == ERROR_LOCK_PATH) 10466 goto out; 10467 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10468 if (res < 0) 10469 goto out; 10470 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10471 vms.curmsg = -1; 10472 if (vms.lastmsg < 0) { 10473 cmd = ast_play_and_wait(chan, "vm-nomore"); 10474 } 10475 } else { 10476 cmd = ast_play_and_wait(chan, "vm-nomore"); 10477 } 10478 } 10479 } 10480 } else /* Delete not valid if we haven't selected a message */ 10481 cmd = 0; 10482 #ifdef IMAP_STORAGE 10483 deleted = 1; 10484 #endif 10485 break; 10486 10487 case '8': /* Forward the current message */ 10488 if (vms.lastmsg > -1) { 10489 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10490 if (cmd == ERROR_LOCK_PATH) { 10491 res = cmd; 10492 goto out; 10493 } 10494 } else { 10495 /* Check if we were listening to urgent 10496 messages. If so, go to regular new messages 10497 instead of saying "no more messages" 10498 */ 10499 if (in_urgent == 1 && vms.newmessages > 0) { 10500 /* Check for new messages */ 10501 in_urgent = 0; 10502 res = close_mailbox(&vms, vmu); 10503 if (res == ERROR_LOCK_PATH) 10504 goto out; 10505 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10506 if (res < 0) 10507 goto out; 10508 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10509 vms.curmsg = -1; 10510 if (vms.lastmsg < 0) { 10511 cmd = ast_play_and_wait(chan, "vm-nomore"); 10512 } 10513 } else { 10514 cmd = ast_play_and_wait(chan, "vm-nomore"); 10515 } 10516 } 10517 break; 10518 case '9': /* Save message to folder */ 10519 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10520 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10521 /* No message selected */ 10522 cmd = 0; 10523 break; 10524 } 10525 if (useadsi) 10526 adsi_folders(chan, 1, "Save to folder..."); 10527 cmd = get_folder2(chan, "vm-savefolder", 1); 10528 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10529 box = 0; /* Shut up compiler */ 10530 if (cmd == '#') { 10531 cmd = 0; 10532 break; 10533 } else if (cmd > 0) { 10534 box = cmd = cmd - '0'; 10535 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10536 if (cmd == ERROR_LOCK_PATH) { 10537 res = cmd; 10538 goto out; 10539 #ifndef IMAP_STORAGE 10540 } else if (!cmd) { 10541 vms.deleted[vms.curmsg] = 1; 10542 #endif 10543 } else { 10544 vms.deleted[vms.curmsg] = 0; 10545 vms.heard[vms.curmsg] = 0; 10546 } 10547 } 10548 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10549 if (useadsi) 10550 adsi_message(chan, &vms); 10551 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10552 if (!cmd) { 10553 cmd = ast_play_and_wait(chan, "vm-message"); 10554 if (!cmd) 10555 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10556 if (!cmd) 10557 cmd = ast_play_and_wait(chan, "vm-savedto"); 10558 if (!cmd) 10559 cmd = vm_play_folder_name(chan, vms.fn); 10560 } else { 10561 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10562 } 10563 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10564 if (vms.curmsg < vms.lastmsg) { 10565 vms.curmsg++; 10566 cmd = play_message(chan, vmu, &vms); 10567 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10568 vms.curmsg = 0; 10569 cmd = play_message(chan, vmu, &vms); 10570 } else { 10571 /* Check if we were listening to urgent 10572 messages. If so, go to regular new messages 10573 instead of saying "no more messages" 10574 */ 10575 if (in_urgent == 1 && vms.newmessages > 0) { 10576 /* Check for new messages */ 10577 in_urgent = 0; 10578 res = close_mailbox(&vms, vmu); 10579 if (res == ERROR_LOCK_PATH) 10580 goto out; 10581 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10582 if (res < 0) 10583 goto out; 10584 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10585 vms.curmsg = -1; 10586 if (vms.lastmsg < 0) { 10587 cmd = ast_play_and_wait(chan, "vm-nomore"); 10588 } 10589 } else { 10590 cmd = ast_play_and_wait(chan, "vm-nomore"); 10591 } 10592 } 10593 } 10594 break; 10595 case '*': /* Help */ 10596 if (!vms.starting) { 10597 cmd = ast_play_and_wait(chan, "vm-onefor"); 10598 if (!strncasecmp(chan->language, "he", 2)) { 10599 cmd = ast_play_and_wait(chan, "vm-for"); 10600 } 10601 if (!cmd) 10602 cmd = vm_play_folder_name(chan, vms.vmbox); 10603 if (!cmd) 10604 cmd = ast_play_and_wait(chan, "vm-opts"); 10605 if (!cmd) 10606 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10607 } else 10608 cmd = 0; 10609 break; 10610 case '0': /* Mailbox options */ 10611 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10612 if (useadsi) 10613 adsi_status(chan, &vms); 10614 break; 10615 default: /* Nothing */ 10616 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10617 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10618 break; 10619 } 10620 } 10621 if ((cmd == 't') || (cmd == '#')) { 10622 /* Timeout */ 10623 res = 0; 10624 } else { 10625 /* Hangup */ 10626 res = -1; 10627 } 10628 10629 out: 10630 if (res > -1) { 10631 ast_stopstream(chan); 10632 adsi_goodbye(chan); 10633 if (valid && res != OPERATOR_EXIT) { 10634 if (silentexit) 10635 res = ast_play_and_wait(chan, "vm-dialout"); 10636 else 10637 res = ast_play_and_wait(chan, "vm-goodbye"); 10638 } 10639 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10640 res = 0; 10641 } 10642 if (useadsi) 10643 ast_adsi_unload_session(chan); 10644 } 10645 if (vmu) 10646 close_mailbox(&vms, vmu); 10647 if (valid) { 10648 int new = 0, old = 0, urgent = 0; 10649 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10650 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10651 /* Urgent flag not passwd to externnotify here */ 10652 run_externnotify(vmu->context, vmu->mailbox, NULL); 10653 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10654 queue_mwi_event(ext_context, urgent, new, old); 10655 } 10656 #ifdef IMAP_STORAGE 10657 /* expunge message - use UID Expunge if supported on IMAP server*/ 10658 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10659 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10660 ast_mutex_lock(&vms.lock); 10661 #ifdef HAVE_IMAP_TK2006 10662 if (LEVELUIDPLUS (vms.mailstream)) { 10663 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10664 } else 10665 #endif 10666 mail_expunge(vms.mailstream); 10667 ast_mutex_unlock(&vms.lock); 10668 } 10669 /* before we delete the state, we should copy pertinent info 10670 * back to the persistent model */ 10671 if (vmu) { 10672 vmstate_delete(&vms); 10673 } 10674 #endif 10675 if (vmu) 10676 free_user(vmu); 10677 10678 #ifdef IMAP_STORAGE 10679 pthread_setspecific(ts_vmstate.key, NULL); 10680 #endif 10681 return res; 10682 }
| 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 9251 of file app_voicemail.c.
References vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
09252 { 09253 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09254 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09255 } else { /* Default to ENGLISH */ 09256 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09257 } 09258 }
| 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 9139 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().
09140 { 09141 int res = 0; 09142 /* Play instructions and wait for new command */ 09143 while (!res) { 09144 if (vms->starting) { 09145 if (vms->lastmsg > -1) { 09146 if (skipadvanced) 09147 res = ast_play_and_wait(chan, "vm-onefor-full"); 09148 else 09149 res = ast_play_and_wait(chan, "vm-onefor"); 09150 if (!res) 09151 res = vm_play_folder_name(chan, vms->vmbox); 09152 } 09153 if (!res) { 09154 if (skipadvanced) 09155 res = ast_play_and_wait(chan, "vm-opts-full"); 09156 else 09157 res = ast_play_and_wait(chan, "vm-opts"); 09158 } 09159 } else { 09160 /* Added for additional help */ 09161 if (skipadvanced) { 09162 res = ast_play_and_wait(chan, "vm-onefor-full"); 09163 if (!res) 09164 res = vm_play_folder_name(chan, vms->vmbox); 09165 res = ast_play_and_wait(chan, "vm-opts-full"); 09166 } 09167 /* Logic: 09168 * If the current message is not the first OR 09169 * if we're listening to the first new message and there are 09170 * also urgent messages, then prompt for navigation to the 09171 * previous message 09172 */ 09173 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09174 res = ast_play_and_wait(chan, "vm-prev"); 09175 } 09176 if (!res && !skipadvanced) 09177 res = ast_play_and_wait(chan, "vm-advopts"); 09178 if (!res) 09179 res = ast_play_and_wait(chan, "vm-repeat"); 09180 /* Logic: 09181 * If we're not listening to the last message OR 09182 * we're listening to the last urgent message and there are 09183 * also new non-urgent messages, then prompt for navigation 09184 * to the next message 09185 */ 09186 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09187 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09188 res = ast_play_and_wait(chan, "vm-next"); 09189 } 09190 if (!res) { 09191 int curmsg_deleted; 09192 #ifdef IMAP_STORAGE 09193 ast_mutex_lock(&vms->lock); 09194 #endif 09195 curmsg_deleted = vms->deleted[vms->curmsg]; 09196 #ifdef IMAP_STORAGE 09197 ast_mutex_unlock(&vms->lock); 09198 #endif 09199 if (!curmsg_deleted) { 09200 res = ast_play_and_wait(chan, "vm-delete"); 09201 } else { 09202 res = ast_play_and_wait(chan, "vm-undelete"); 09203 } 09204 if (!res) { 09205 res = ast_play_and_wait(chan, "vm-toforward"); 09206 } 09207 if (!res) { 09208 res = ast_play_and_wait(chan, "vm-savemessage"); 09209 } 09210 } 09211 } 09212 if (!res) { 09213 res = ast_play_and_wait(chan, "vm-helpexit"); 09214 } 09215 if (!res) 09216 res = ast_waitfordigit(chan, 6000); 09217 if (!res) { 09218 vms->repeats++; 09219 if (vms->repeats > 2) { 09220 res = 't'; 09221 } 09222 } 09223 } 09224 return res; 09225 }
| 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 9227 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().
09228 { 09229 int res = 0; 09230 /* Play instructions and wait for new command */ 09231 while (!res) { 09232 if (vms->lastmsg > -1) { 09233 res = ast_play_and_wait(chan, "vm-listen"); 09234 if (!res) 09235 res = vm_play_folder_name(chan, vms->vmbox); 09236 if (!res) 09237 res = ast_play_and_wait(chan, "press"); 09238 if (!res) 09239 res = ast_play_and_wait(chan, "digits/1"); 09240 } 09241 if (!res) 09242 res = ast_play_and_wait(chan, "vm-opts"); 09243 if (!res) { 09244 vms->starting = 0; 09245 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09246 } 09247 } 09248 return res; 09249 }
| static int vm_intro | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 9077 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().
09078 { 09079 char prefile[256]; 09080 09081 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09082 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09083 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09084 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09085 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09086 ast_play_and_wait(chan, "vm-tempgreetactive"); 09087 } 09088 DISPOSE(prefile, -1); 09089 } 09090 09091 /* Play voicemail intro - syntax is different for different languages */ 09092 if (0) { 09093 return 0; 09094 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09095 return vm_intro_cs(chan, vms); 09096 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09097 static int deprecation_warning = 0; 09098 if (deprecation_warning++ % 10 == 0) { 09099 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09100 } 09101 return vm_intro_cs(chan, vms); 09102 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09103 return vm_intro_de(chan, vms); 09104 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09105 return vm_intro_es(chan, vms); 09106 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09107 return vm_intro_fr(chan, vms); 09108 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09109 return vm_intro_gr(chan, vms); 09110 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09111 return vm_intro_he(chan, vms); 09112 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09113 return vm_intro_it(chan, vms); 09114 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09115 return vm_intro_nl(chan, vms); 09116 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09117 return vm_intro_no(chan, vms); 09118 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09119 return vm_intro_pl(chan, vms); 09120 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09121 return vm_intro_pt_BR(chan, vms); 09122 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09123 return vm_intro_pt(chan, vms); 09124 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09125 return vm_intro_multilang(chan, vms, "n"); 09126 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09127 return vm_intro_se(chan, vms); 09128 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09129 return vm_intro_multilang(chan, vms, "n"); 09130 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09131 return vm_intro_vi(chan, vms); 09132 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09133 return vm_intro_zh(chan, vms); 09134 } else { /* Default to ENGLISH */ 09135 return vm_intro_en(chan, vms); 09136 } 09137 }
| static int vm_intro_cs | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8947 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().
08948 { 08949 int res; 08950 res = ast_play_and_wait(chan, "vm-youhave"); 08951 if (!res) { 08952 if (vms->newmessages) { 08953 if (vms->newmessages == 1) { 08954 res = ast_play_and_wait(chan, "digits/jednu"); 08955 } else { 08956 res = say_and_wait(chan, vms->newmessages, chan->language); 08957 } 08958 if (!res) { 08959 if ((vms->newmessages == 1)) 08960 res = ast_play_and_wait(chan, "vm-novou"); 08961 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08962 res = ast_play_and_wait(chan, "vm-nove"); 08963 if (vms->newmessages > 4) 08964 res = ast_play_and_wait(chan, "vm-novych"); 08965 } 08966 if (vms->oldmessages && !res) 08967 res = ast_play_and_wait(chan, "vm-and"); 08968 else if (!res) { 08969 if ((vms->newmessages == 1)) 08970 res = ast_play_and_wait(chan, "vm-zpravu"); 08971 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08972 res = ast_play_and_wait(chan, "vm-zpravy"); 08973 if (vms->newmessages > 4) 08974 res = ast_play_and_wait(chan, "vm-zprav"); 08975 } 08976 } 08977 if (!res && vms->oldmessages) { 08978 res = say_and_wait(chan, vms->oldmessages, chan->language); 08979 if (!res) { 08980 if ((vms->oldmessages == 1)) 08981 res = ast_play_and_wait(chan, "vm-starou"); 08982 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08983 res = ast_play_and_wait(chan, "vm-stare"); 08984 if (vms->oldmessages > 4) 08985 res = ast_play_and_wait(chan, "vm-starych"); 08986 } 08987 if (!res) { 08988 if ((vms->oldmessages == 1)) 08989 res = ast_play_and_wait(chan, "vm-zpravu"); 08990 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08991 res = ast_play_and_wait(chan, "vm-zpravy"); 08992 if (vms->oldmessages > 4) 08993 res = ast_play_and_wait(chan, "vm-zprav"); 08994 } 08995 } 08996 if (!res) { 08997 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08998 res = ast_play_and_wait(chan, "vm-no"); 08999 if (!res) 09000 res = ast_play_and_wait(chan, "vm-zpravy"); 09001 } 09002 } 09003 } 09004 return res; 09005 }
| static int vm_intro_de | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8643 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().
08644 { 08645 /* Introduce messages they have */ 08646 int res; 08647 res = ast_play_and_wait(chan, "vm-youhave"); 08648 if (!res) { 08649 if (vms->newmessages) { 08650 if ((vms->newmessages == 1)) 08651 res = ast_play_and_wait(chan, "digits/1F"); 08652 else 08653 res = say_and_wait(chan, vms->newmessages, chan->language); 08654 if (!res) 08655 res = ast_play_and_wait(chan, "vm-INBOX"); 08656 if (vms->oldmessages && !res) 08657 res = ast_play_and_wait(chan, "vm-and"); 08658 else if (!res) { 08659 if ((vms->newmessages == 1)) 08660 res = ast_play_and_wait(chan, "vm-message"); 08661 else 08662 res = ast_play_and_wait(chan, "vm-messages"); 08663 } 08664 08665 } 08666 if (!res && vms->oldmessages) { 08667 if (vms->oldmessages == 1) 08668 res = ast_play_and_wait(chan, "digits/1F"); 08669 else 08670 res = say_and_wait(chan, vms->oldmessages, chan->language); 08671 if (!res) 08672 res = ast_play_and_wait(chan, "vm-Old"); 08673 if (!res) { 08674 if (vms->oldmessages == 1) 08675 res = ast_play_and_wait(chan, "vm-message"); 08676 else 08677 res = ast_play_and_wait(chan, "vm-messages"); 08678 } 08679 } 08680 if (!res) { 08681 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08682 res = ast_play_and_wait(chan, "vm-no"); 08683 if (!res) 08684 res = ast_play_and_wait(chan, "vm-messages"); 08685 } 08686 } 08687 } 08688 return res; 08689 }
| static int vm_intro_en | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8392 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().
08393 { 08394 int res; 08395 08396 /* Introduce messages they have */ 08397 res = ast_play_and_wait(chan, "vm-youhave"); 08398 if (!res) { 08399 if (vms->urgentmessages) { 08400 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08401 if (!res) 08402 res = ast_play_and_wait(chan, "vm-Urgent"); 08403 if ((vms->oldmessages || vms->newmessages) && !res) { 08404 res = ast_play_and_wait(chan, "vm-and"); 08405 } else if (!res) { 08406 if ((vms->urgentmessages == 1)) 08407 res = ast_play_and_wait(chan, "vm-message"); 08408 else 08409 res = ast_play_and_wait(chan, "vm-messages"); 08410 } 08411 } 08412 if (vms->newmessages) { 08413 res = say_and_wait(chan, vms->newmessages, chan->language); 08414 if (!res) 08415 res = ast_play_and_wait(chan, "vm-INBOX"); 08416 if (vms->oldmessages && !res) 08417 res = ast_play_and_wait(chan, "vm-and"); 08418 else if (!res) { 08419 if ((vms->newmessages == 1)) 08420 res = ast_play_and_wait(chan, "vm-message"); 08421 else 08422 res = ast_play_and_wait(chan, "vm-messages"); 08423 } 08424 08425 } 08426 if (!res && vms->oldmessages) { 08427 res = say_and_wait(chan, vms->oldmessages, chan->language); 08428 if (!res) 08429 res = ast_play_and_wait(chan, "vm-Old"); 08430 if (!res) { 08431 if (vms->oldmessages == 1) 08432 res = ast_play_and_wait(chan, "vm-message"); 08433 else 08434 res = ast_play_and_wait(chan, "vm-messages"); 08435 } 08436 } 08437 if (!res) { 08438 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08439 res = ast_play_and_wait(chan, "vm-no"); 08440 if (!res) 08441 res = ast_play_and_wait(chan, "vm-messages"); 08442 } 08443 } 08444 } 08445 return res; 08446 }
| static int vm_intro_es | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8692 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().
08693 { 08694 /* Introduce messages they have */ 08695 int res; 08696 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08697 res = ast_play_and_wait(chan, "vm-youhaveno"); 08698 if (!res) 08699 res = ast_play_and_wait(chan, "vm-messages"); 08700 } else { 08701 res = ast_play_and_wait(chan, "vm-youhave"); 08702 } 08703 if (!res) { 08704 if (vms->newmessages) { 08705 if (!res) { 08706 if ((vms->newmessages == 1)) { 08707 res = ast_play_and_wait(chan, "digits/1M"); 08708 if (!res) 08709 res = ast_play_and_wait(chan, "vm-message"); 08710 if (!res) 08711 res = ast_play_and_wait(chan, "vm-INBOXs"); 08712 } else { 08713 res = say_and_wait(chan, vms->newmessages, chan->language); 08714 if (!res) 08715 res = ast_play_and_wait(chan, "vm-messages"); 08716 if (!res) 08717 res = ast_play_and_wait(chan, "vm-INBOX"); 08718 } 08719 } 08720 if (vms->oldmessages && !res) 08721 res = ast_play_and_wait(chan, "vm-and"); 08722 } 08723 if (vms->oldmessages) { 08724 if (!res) { 08725 if (vms->oldmessages == 1) { 08726 res = ast_play_and_wait(chan, "digits/1M"); 08727 if (!res) 08728 res = ast_play_and_wait(chan, "vm-message"); 08729 if (!res) 08730 res = ast_play_and_wait(chan, "vm-Olds"); 08731 } else { 08732 res = say_and_wait(chan, vms->oldmessages, chan->language); 08733 if (!res) 08734 res = ast_play_and_wait(chan, "vm-messages"); 08735 if (!res) 08736 res = ast_play_and_wait(chan, "vm-Old"); 08737 } 08738 } 08739 } 08740 } 08741 return res; 08742 }
| static int vm_intro_fr | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8790 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().
08791 { 08792 /* Introduce messages they have */ 08793 int res; 08794 res = ast_play_and_wait(chan, "vm-youhave"); 08795 if (!res) { 08796 if (vms->newmessages) { 08797 res = say_and_wait(chan, vms->newmessages, chan->language); 08798 if (!res) 08799 res = ast_play_and_wait(chan, "vm-INBOX"); 08800 if (vms->oldmessages && !res) 08801 res = ast_play_and_wait(chan, "vm-and"); 08802 else if (!res) { 08803 if ((vms->newmessages == 1)) 08804 res = ast_play_and_wait(chan, "vm-message"); 08805 else 08806 res = ast_play_and_wait(chan, "vm-messages"); 08807 } 08808 08809 } 08810 if (!res && vms->oldmessages) { 08811 res = say_and_wait(chan, vms->oldmessages, chan->language); 08812 if (!res) 08813 res = ast_play_and_wait(chan, "vm-Old"); 08814 if (!res) { 08815 if (vms->oldmessages == 1) 08816 res = ast_play_and_wait(chan, "vm-message"); 08817 else 08818 res = ast_play_and_wait(chan, "vm-messages"); 08819 } 08820 } 08821 if (!res) { 08822 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08823 res = ast_play_and_wait(chan, "vm-no"); 08824 if (!res) 08825 res = ast_play_and_wait(chan, "vm-messages"); 08826 } 08827 } 08828 } 08829 return res; 08830 }
| static int vm_intro_gr | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8191 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().
08192 { 08193 int res = 0; 08194 08195 if (vms->newmessages) { 08196 res = ast_play_and_wait(chan, "vm-youhave"); 08197 if (!res) 08198 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08199 if (!res) { 08200 if ((vms->newmessages == 1)) { 08201 res = ast_play_and_wait(chan, "vm-INBOX"); 08202 if (!res) 08203 res = ast_play_and_wait(chan, "vm-message"); 08204 } else { 08205 res = ast_play_and_wait(chan, "vm-INBOXs"); 08206 if (!res) 08207 res = ast_play_and_wait(chan, "vm-messages"); 08208 } 08209 } 08210 } else if (vms->oldmessages){ 08211 res = ast_play_and_wait(chan, "vm-youhave"); 08212 if (!res) 08213 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08214 if ((vms->oldmessages == 1)){ 08215 res = ast_play_and_wait(chan, "vm-Old"); 08216 if (!res) 08217 res = ast_play_and_wait(chan, "vm-message"); 08218 } else { 08219 res = ast_play_and_wait(chan, "vm-Olds"); 08220 if (!res) 08221 res = ast_play_and_wait(chan, "vm-messages"); 08222 } 08223 } else if (!vms->oldmessages && !vms->newmessages) 08224 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08225 return res; 08226 }
| static int vm_intro_he | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8325 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().
08326 { 08327 int res = 0; 08328 08329 /* Introduce messages they have */ 08330 if (!res) { 08331 if ((vms->newmessages) || (vms->oldmessages)) { 08332 res = ast_play_and_wait(chan, "vm-youhave"); 08333 } 08334 /* 08335 * The word "shtei" refers to the number 2 in hebrew when performing a count 08336 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08337 * an element, this is one of them. 08338 */ 08339 if (vms->newmessages) { 08340 if (!res) { 08341 if (vms->newmessages == 1) { 08342 res = ast_play_and_wait(chan, "vm-INBOX1"); 08343 } else { 08344 if (vms->newmessages == 2) { 08345 res = ast_play_and_wait(chan, "vm-shtei"); 08346 } else { 08347 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08348 } 08349 res = ast_play_and_wait(chan, "vm-INBOX"); 08350 } 08351 } 08352 if (vms->oldmessages && !res) { 08353 res = ast_play_and_wait(chan, "vm-and"); 08354 if (vms->oldmessages == 1) { 08355 res = ast_play_and_wait(chan, "vm-Old1"); 08356 } else { 08357 if (vms->oldmessages == 2) { 08358 res = ast_play_and_wait(chan, "vm-shtei"); 08359 } else { 08360 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08361 } 08362 res = ast_play_and_wait(chan, "vm-Old"); 08363 } 08364 } 08365 } 08366 if (!res && vms->oldmessages && !vms->newmessages) { 08367 if (!res) { 08368 if (vms->oldmessages == 1) { 08369 res = ast_play_and_wait(chan, "vm-Old1"); 08370 } else { 08371 if (vms->oldmessages == 2) { 08372 res = ast_play_and_wait(chan, "vm-shtei"); 08373 } else { 08374 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08375 } 08376 res = ast_play_and_wait(chan, "vm-Old"); 08377 } 08378 } 08379 } 08380 if (!res) { 08381 if (!vms->oldmessages && !vms->newmessages) { 08382 if (!res) { 08383 res = ast_play_and_wait(chan, "vm-nomessages"); 08384 } 08385 } 08386 } 08387 } 08388 return res; 08389 }
| static int vm_intro_it | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8449 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().
08450 { 08451 /* Introduce messages they have */ 08452 int res; 08453 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08454 res = ast_play_and_wait(chan, "vm-no") || 08455 ast_play_and_wait(chan, "vm-message"); 08456 else 08457 res = ast_play_and_wait(chan, "vm-youhave"); 08458 if (!res && vms->newmessages) { 08459 res = (vms->newmessages == 1) ? 08460 ast_play_and_wait(chan, "digits/un") || 08461 ast_play_and_wait(chan, "vm-nuovo") || 08462 ast_play_and_wait(chan, "vm-message") : 08463 /* 2 or more new messages */ 08464 say_and_wait(chan, vms->newmessages, chan->language) || 08465 ast_play_and_wait(chan, "vm-nuovi") || 08466 ast_play_and_wait(chan, "vm-messages"); 08467 if (!res && vms->oldmessages) 08468 res = ast_play_and_wait(chan, "vm-and"); 08469 } 08470 if (!res && vms->oldmessages) { 08471 res = (vms->oldmessages == 1) ? 08472 ast_play_and_wait(chan, "digits/un") || 08473 ast_play_and_wait(chan, "vm-vecchio") || 08474 ast_play_and_wait(chan, "vm-message") : 08475 /* 2 or more old messages */ 08476 say_and_wait(chan, vms->oldmessages, chan->language) || 08477 ast_play_and_wait(chan, "vm-vecchi") || 08478 ast_play_and_wait(chan, "vm-messages"); 08479 } 08480 return res; 08481 }
| static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| const char | message_gender[] | |||
| ) | [static] |
Definition at line 8285 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().
08286 { 08287 int res; 08288 int lastnum = 0; 08289 08290 res = ast_play_and_wait(chan, "vm-youhave"); 08291 08292 if (!res && vms->newmessages) { 08293 lastnum = vms->newmessages; 08294 08295 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08296 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08297 } 08298 08299 if (!res && vms->oldmessages) { 08300 res = ast_play_and_wait(chan, "vm-and"); 08301 } 08302 } 08303 08304 if (!res && vms->oldmessages) { 08305 lastnum = vms->oldmessages; 08306 08307 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08308 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08309 } 08310 } 08311 08312 if (!res) { 08313 if (lastnum == 0) { 08314 res = ast_play_and_wait(chan, "vm-no"); 08315 } 08316 if (!res) { 08317 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08318 } 08319 } 08320 08321 return res; 08322 }
| static int vm_intro_nl | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8833 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().
08834 { 08835 /* Introduce messages they have */ 08836 int res; 08837 res = ast_play_and_wait(chan, "vm-youhave"); 08838 if (!res) { 08839 if (vms->newmessages) { 08840 res = say_and_wait(chan, vms->newmessages, chan->language); 08841 if (!res) { 08842 if (vms->newmessages == 1) 08843 res = ast_play_and_wait(chan, "vm-INBOXs"); 08844 else 08845 res = ast_play_and_wait(chan, "vm-INBOX"); 08846 } 08847 if (vms->oldmessages && !res) 08848 res = ast_play_and_wait(chan, "vm-and"); 08849 else if (!res) { 08850 if ((vms->newmessages == 1)) 08851 res = ast_play_and_wait(chan, "vm-message"); 08852 else 08853 res = ast_play_and_wait(chan, "vm-messages"); 08854 } 08855 08856 } 08857 if (!res && vms->oldmessages) { 08858 res = say_and_wait(chan, vms->oldmessages, chan->language); 08859 if (!res) { 08860 if (vms->oldmessages == 1) 08861 res = ast_play_and_wait(chan, "vm-Olds"); 08862 else 08863 res = ast_play_and_wait(chan, "vm-Old"); 08864 } 08865 if (!res) { 08866 if (vms->oldmessages == 1) 08867 res = ast_play_and_wait(chan, "vm-message"); 08868 else 08869 res = ast_play_and_wait(chan, "vm-messages"); 08870 } 08871 } 08872 if (!res) { 08873 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08874 res = ast_play_and_wait(chan, "vm-no"); 08875 if (!res) 08876 res = ast_play_and_wait(chan, "vm-messages"); 08877 } 08878 } 08879 } 08880 return res; 08881 }
| static int vm_intro_no | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8599 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().
08600 { 08601 /* Introduce messages they have */ 08602 int res; 08603 08604 res = ast_play_and_wait(chan, "vm-youhave"); 08605 if (res) 08606 return res; 08607 08608 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08609 res = ast_play_and_wait(chan, "vm-no"); 08610 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08611 return res; 08612 } 08613 08614 if (vms->newmessages) { 08615 if ((vms->newmessages == 1)) { 08616 res = ast_play_and_wait(chan, "digits/1"); 08617 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08618 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08619 } else { 08620 res = say_and_wait(chan, vms->newmessages, chan->language); 08621 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08622 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08623 } 08624 if (!res && vms->oldmessages) 08625 res = ast_play_and_wait(chan, "vm-and"); 08626 } 08627 if (!res && vms->oldmessages) { 08628 if (vms->oldmessages == 1) { 08629 res = ast_play_and_wait(chan, "digits/1"); 08630 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08631 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08632 } else { 08633 res = say_and_wait(chan, vms->oldmessages, chan->language); 08634 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08635 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08636 } 08637 } 08638 08639 return res; 08640 }
| static int vm_intro_pl | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8484 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08485 { 08486 /* Introduce messages they have */ 08487 int res; 08488 div_t num; 08489 08490 if (!vms->oldmessages && !vms->newmessages) { 08491 res = ast_play_and_wait(chan, "vm-no"); 08492 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08493 return res; 08494 } else { 08495 res = ast_play_and_wait(chan, "vm-youhave"); 08496 } 08497 08498 if (vms->newmessages) { 08499 num = div(vms->newmessages, 10); 08500 if (vms->newmessages == 1) { 08501 res = ast_play_and_wait(chan, "digits/1-a"); 08502 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08503 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08504 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08505 if (num.rem == 2) { 08506 if (!num.quot) { 08507 res = ast_play_and_wait(chan, "digits/2-ie"); 08508 } else { 08509 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08510 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08511 } 08512 } else { 08513 res = say_and_wait(chan, vms->newmessages, chan->language); 08514 } 08515 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08516 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08517 } else { 08518 res = say_and_wait(chan, vms->newmessages, chan->language); 08519 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08520 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08521 } 08522 if (!res && vms->oldmessages) 08523 res = ast_play_and_wait(chan, "vm-and"); 08524 } 08525 if (!res && vms->oldmessages) { 08526 num = div(vms->oldmessages, 10); 08527 if (vms->oldmessages == 1) { 08528 res = ast_play_and_wait(chan, "digits/1-a"); 08529 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08530 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08531 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08532 if (num.rem == 2) { 08533 if (!num.quot) { 08534 res = ast_play_and_wait(chan, "digits/2-ie"); 08535 } else { 08536 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08537 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08538 } 08539 } else { 08540 res = say_and_wait(chan, vms->oldmessages, chan->language); 08541 } 08542 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08543 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08544 } else { 08545 res = say_and_wait(chan, vms->oldmessages, chan->language); 08546 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08547 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08548 } 08549 } 08550 08551 return res; 08552 }
| static int vm_intro_pt | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8884 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().
08885 { 08886 /* Introduce messages they have */ 08887 int res; 08888 res = ast_play_and_wait(chan, "vm-youhave"); 08889 if (!res) { 08890 if (vms->newmessages) { 08891 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08892 if (!res) { 08893 if ((vms->newmessages == 1)) { 08894 res = ast_play_and_wait(chan, "vm-message"); 08895 if (!res) 08896 res = ast_play_and_wait(chan, "vm-INBOXs"); 08897 } else { 08898 res = ast_play_and_wait(chan, "vm-messages"); 08899 if (!res) 08900 res = ast_play_and_wait(chan, "vm-INBOX"); 08901 } 08902 } 08903 if (vms->oldmessages && !res) 08904 res = ast_play_and_wait(chan, "vm-and"); 08905 } 08906 if (!res && vms->oldmessages) { 08907 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08908 if (!res) { 08909 if (vms->oldmessages == 1) { 08910 res = ast_play_and_wait(chan, "vm-message"); 08911 if (!res) 08912 res = ast_play_and_wait(chan, "vm-Olds"); 08913 } else { 08914 res = ast_play_and_wait(chan, "vm-messages"); 08915 if (!res) 08916 res = ast_play_and_wait(chan, "vm-Old"); 08917 } 08918 } 08919 } 08920 if (!res) { 08921 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08922 res = ast_play_and_wait(chan, "vm-no"); 08923 if (!res) 08924 res = ast_play_and_wait(chan, "vm-messages"); 08925 } 08926 } 08927 } 08928 return res; 08929 }
| static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8745 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().
08745 { 08746 /* Introduce messages they have */ 08747 int res; 08748 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08749 res = ast_play_and_wait(chan, "vm-nomessages"); 08750 return res; 08751 } else { 08752 res = ast_play_and_wait(chan, "vm-youhave"); 08753 } 08754 if (vms->newmessages) { 08755 if (!res) 08756 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08757 if ((vms->newmessages == 1)) { 08758 if (!res) 08759 res = ast_play_and_wait(chan, "vm-message"); 08760 if (!res) 08761 res = ast_play_and_wait(chan, "vm-INBOXs"); 08762 } else { 08763 if (!res) 08764 res = ast_play_and_wait(chan, "vm-messages"); 08765 if (!res) 08766 res = ast_play_and_wait(chan, "vm-INBOX"); 08767 } 08768 if (vms->oldmessages && !res) 08769 res = ast_play_and_wait(chan, "vm-and"); 08770 } 08771 if (vms->oldmessages) { 08772 if (!res) 08773 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08774 if (vms->oldmessages == 1) { 08775 if (!res) 08776 res = ast_play_and_wait(chan, "vm-message"); 08777 if (!res) 08778 res = ast_play_and_wait(chan, "vm-Olds"); 08779 } else { 08780 if (!res) 08781 res = ast_play_and_wait(chan, "vm-messages"); 08782 if (!res) 08783 res = ast_play_and_wait(chan, "vm-Old"); 08784 } 08785 } 08786 return res; 08787 }
| static int vm_intro_se | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8555 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().
08556 { 08557 /* Introduce messages they have */ 08558 int res; 08559 08560 res = ast_play_and_wait(chan, "vm-youhave"); 08561 if (res) 08562 return res; 08563 08564 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08565 res = ast_play_and_wait(chan, "vm-no"); 08566 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08567 return res; 08568 } 08569 08570 if (vms->newmessages) { 08571 if ((vms->newmessages == 1)) { 08572 res = ast_play_and_wait(chan, "digits/ett"); 08573 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08574 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08575 } else { 08576 res = say_and_wait(chan, vms->newmessages, chan->language); 08577 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08578 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08579 } 08580 if (!res && vms->oldmessages) 08581 res = ast_play_and_wait(chan, "vm-and"); 08582 } 08583 if (!res && vms->oldmessages) { 08584 if (vms->oldmessages == 1) { 08585 res = ast_play_and_wait(chan, "digits/ett"); 08586 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08587 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08588 } else { 08589 res = say_and_wait(chan, vms->oldmessages, chan->language); 08590 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08591 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08592 } 08593 } 08594 08595 return res; 08596 }
| static int vm_intro_vi | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 9047 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
09048 { 09049 int res; 09050 09051 /* Introduce messages they have */ 09052 res = ast_play_and_wait(chan, "vm-youhave"); 09053 if (!res) { 09054 if (vms->newmessages) { 09055 res = say_and_wait(chan, vms->newmessages, chan->language); 09056 if (!res) 09057 res = ast_play_and_wait(chan, "vm-INBOX"); 09058 if (vms->oldmessages && !res) 09059 res = ast_play_and_wait(chan, "vm-and"); 09060 } 09061 if (!res && vms->oldmessages) { 09062 res = say_and_wait(chan, vms->oldmessages, chan->language); 09063 if (!res) 09064 res = ast_play_and_wait(chan, "vm-Old"); 09065 } 09066 if (!res) { 09067 if (!vms->oldmessages && !vms->newmessages) { 09068 res = ast_play_and_wait(chan, "vm-no"); 09069 if (!res) 09070 res = ast_play_and_wait(chan, "vm-message"); 09071 } 09072 } 09073 } 09074 return res; 09075 }
| static int vm_intro_zh | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 9008 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
09009 { 09010 int res; 09011 /* Introduce messages they have */ 09012 res = ast_play_and_wait(chan, "vm-you"); 09013 09014 if (!res && vms->newmessages) { 09015 res = ast_play_and_wait(chan, "vm-have"); 09016 if (!res) 09017 res = say_and_wait(chan, vms->newmessages, chan->language); 09018 if (!res) 09019 res = ast_play_and_wait(chan, "vm-tong"); 09020 if (!res) 09021 res = ast_play_and_wait(chan, "vm-INBOX"); 09022 if (vms->oldmessages && !res) 09023 res = ast_play_and_wait(chan, "vm-and"); 09024 else if (!res) 09025 res = ast_play_and_wait(chan, "vm-messages"); 09026 } 09027 if (!res && vms->oldmessages) { 09028 res = ast_play_and_wait(chan, "vm-have"); 09029 if (!res) 09030 res = say_and_wait(chan, vms->oldmessages, chan->language); 09031 if (!res) 09032 res = ast_play_and_wait(chan, "vm-tong"); 09033 if (!res) 09034 res = ast_play_and_wait(chan, "vm-Old"); 09035 if (!res) 09036 res = ast_play_and_wait(chan, "vm-messages"); 09037 } 09038 if (!res && !vms->oldmessages && !vms->newmessages) { 09039 res = ast_play_and_wait(chan, "vm-haveno"); 09040 if (!res) 09041 res = ast_play_and_wait(chan, "vm-messages"); 09042 } 09043 return res; 09044 }
| 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 9261 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().
09262 { 09263 int cmd = 0; 09264 int duration = 0; 09265 int tries = 0; 09266 char newpassword[80] = ""; 09267 char newpassword2[80] = ""; 09268 char prefile[PATH_MAX] = ""; 09269 unsigned char buf[256]; 09270 int bytes = 0; 09271 09272 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09273 if (ast_adsi_available(chan)) { 09274 bytes += adsi_logo(buf + bytes); 09275 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09276 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09277 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09278 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09279 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09280 } 09281 09282 /* If forcename is set, have the user record their name */ 09283 if (ast_test_flag(vmu, VM_FORCENAME)) { 09284 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09285 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09286 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09287 if (cmd < 0 || cmd == 't' || cmd == '#') 09288 return cmd; 09289 } 09290 } 09291 09292 /* If forcegreetings is set, have the user record their greetings */ 09293 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09294 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09295 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09296 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09297 if (cmd < 0 || cmd == 't' || cmd == '#') 09298 return cmd; 09299 } 09300 09301 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09302 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09303 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09304 if (cmd < 0 || cmd == 't' || cmd == '#') 09305 return cmd; 09306 } 09307 } 09308 09309 /* 09310 * Change the password last since new users will be able to skip over any steps this one comes before 09311 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09312 */ 09313 for (;;) { 09314 newpassword[1] = '\0'; 09315 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09316 if (cmd == '#') 09317 newpassword[0] = '\0'; 09318 if (cmd < 0 || cmd == 't' || cmd == '#') 09319 return cmd; 09320 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09321 if (cmd < 0 || cmd == 't' || cmd == '#') 09322 return cmd; 09323 cmd = check_password(vmu, newpassword); /* perform password validation */ 09324 if (cmd != 0) { 09325 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09326 cmd = ast_play_and_wait(chan, vm_invalid_password); 09327 } else { 09328 newpassword2[1] = '\0'; 09329 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09330 if (cmd == '#') 09331 newpassword2[0] = '\0'; 09332 if (cmd < 0 || cmd == 't' || cmd == '#') 09333 return cmd; 09334 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09335 if (cmd < 0 || cmd == 't' || cmd == '#') 09336 return cmd; 09337 if (!strcmp(newpassword, newpassword2)) 09338 break; 09339 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09340 cmd = ast_play_and_wait(chan, vm_mismatch); 09341 } 09342 if (++tries == 3) 09343 return -1; 09344 if (cmd != 0) { 09345 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09346 } 09347 } 09348 if (pwdchange & PWDCHANGE_INTERNAL) 09349 vm_change_password(vmu, newpassword); 09350 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09351 vm_change_password_shell(vmu, newpassword); 09352 09353 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09354 cmd = ast_play_and_wait(chan, vm_passchanged); 09355 09356 return cmd; 09357 }
| 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 9359 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().
09360 { 09361 int cmd = 0; 09362 int retries = 0; 09363 int duration = 0; 09364 char newpassword[80] = ""; 09365 char newpassword2[80] = ""; 09366 char prefile[PATH_MAX] = ""; 09367 unsigned char buf[256]; 09368 int bytes = 0; 09369 09370 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09371 if (ast_adsi_available(chan)) { 09372 bytes += adsi_logo(buf + bytes); 09373 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09374 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09375 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09376 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09377 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09378 } 09379 while ((cmd >= 0) && (cmd != 't')) { 09380 if (cmd) 09381 retries = 0; 09382 switch (cmd) { 09383 case '1': /* Record your unavailable message */ 09384 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09385 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09386 break; 09387 case '2': /* Record your busy message */ 09388 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09389 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09390 break; 09391 case '3': /* Record greeting */ 09392 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09393 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09394 break; 09395 case '4': /* manage the temporary greeting */ 09396 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09397 break; 09398 case '5': /* change password */ 09399 if (vmu->password[0] == '-') { 09400 cmd = ast_play_and_wait(chan, "vm-no"); 09401 break; 09402 } 09403 newpassword[1] = '\0'; 09404 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09405 if (cmd == '#') 09406 newpassword[0] = '\0'; 09407 else { 09408 if (cmd < 0) 09409 break; 09410 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09411 break; 09412 } 09413 } 09414 cmd = check_password(vmu, newpassword); /* perform password validation */ 09415 if (cmd != 0) { 09416 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09417 cmd = ast_play_and_wait(chan, vm_invalid_password); 09418 if (!cmd) { 09419 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09420 } 09421 break; 09422 } 09423 newpassword2[1] = '\0'; 09424 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09425 if (cmd == '#') 09426 newpassword2[0] = '\0'; 09427 else { 09428 if (cmd < 0) 09429 break; 09430 09431 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09432 break; 09433 } 09434 } 09435 if (strcmp(newpassword, newpassword2)) { 09436 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09437 cmd = ast_play_and_wait(chan, vm_mismatch); 09438 if (!cmd) { 09439 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09440 } 09441 break; 09442 } 09443 09444 if (pwdchange & PWDCHANGE_INTERNAL) { 09445 vm_change_password(vmu, newpassword); 09446 } 09447 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09448 vm_change_password_shell(vmu, newpassword); 09449 } 09450 09451 ast_debug(1, "User %s set password to %s of length %d\n", 09452 vms->username, newpassword, (int) strlen(newpassword)); 09453 cmd = ast_play_and_wait(chan, vm_passchanged); 09454 break; 09455 case '*': 09456 cmd = 't'; 09457 break; 09458 default: 09459 cmd = 0; 09460 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09461 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09462 if (ast_fileexists(prefile, NULL, NULL)) { 09463 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09464 } 09465 DISPOSE(prefile, -1); 09466 if (!cmd) { 09467 cmd = ast_play_and_wait(chan, "vm-options"); 09468 } 09469 if (!cmd) { 09470 cmd = ast_waitfordigit(chan, 6000); 09471 } 09472 if (!cmd) { 09473 retries++; 09474 } 09475 if (retries > 3) { 09476 cmd = 't'; 09477 } 09478 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09479 } 09480 } 09481 if (cmd == 't') 09482 cmd = 0; 09483 return cmd; 09484 }
| static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
| char * | mbox | |||
| ) | [static] |
Definition at line 8154 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().
08155 { 08156 int cmd; 08157 08158 if ( !strncasecmp(chan->language, "it", 2) || 08159 !strncasecmp(chan->language, "es", 2) || 08160 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08161 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08162 return cmd ? cmd : ast_play_and_wait(chan, box); 08163 } else if (!strncasecmp(chan->language, "gr", 2)) { 08164 return vm_play_folder_name_gr(chan, box); 08165 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08166 return ast_play_and_wait(chan, box); 08167 } else if (!strncasecmp(chan->language, "pl", 2)) { 08168 return vm_play_folder_name_pl(chan, box); 08169 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08170 return vm_play_folder_name_ua(chan, box); 08171 } else if (!strncasecmp(chan->language, "vi", 2)) { 08172 return ast_play_and_wait(chan, box); 08173 } else { /* Default English */ 08174 cmd = ast_play_and_wait(chan, box); 08175 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08176 } 08177 }
| static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 8107 of file app_voicemail.c.
References ast_alloca, and ast_play_and_wait().
Referenced by vm_play_folder_name().
08108 { 08109 int cmd; 08110 char *buf; 08111 08112 buf = ast_alloca(strlen(box) + 2); 08113 strcpy(buf, box); 08114 strcat(buf, "s"); 08115 08116 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08117 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08118 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08119 } else { 08120 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08121 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08122 } 08123 }
| static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 8125 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08126 { 08127 int cmd; 08128 08129 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08130 if (!strcasecmp(box, "vm-INBOX")) 08131 cmd = ast_play_and_wait(chan, "vm-new-e"); 08132 else 08133 cmd = ast_play_and_wait(chan, "vm-old-e"); 08134 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08135 } else { 08136 cmd = ast_play_and_wait(chan, "vm-messages"); 08137 return cmd ? cmd : ast_play_and_wait(chan, box); 08138 } 08139 }
| static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 8141 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08142 { 08143 int cmd; 08144 08145 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08146 cmd = ast_play_and_wait(chan, "vm-messages"); 08147 return cmd ? cmd : ast_play_and_wait(chan, box); 08148 } else { 08149 cmd = ast_play_and_wait(chan, box); 08150 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08151 } 08152 }
| 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 9502 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().
09503 { 09504 int cmd = 0; 09505 int retries = 0; 09506 int duration = 0; 09507 char prefile[PATH_MAX] = ""; 09508 unsigned char buf[256]; 09509 int bytes = 0; 09510 09511 if (ast_adsi_available(chan)) { 09512 bytes += adsi_logo(buf + bytes); 09513 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09514 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09515 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09516 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09517 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09518 } 09519 09520 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09521 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09522 while ((cmd >= 0) && (cmd != 't')) { 09523 if (cmd) 09524 retries = 0; 09525 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09526 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09527 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09528 if (cmd == -1) { 09529 break; 09530 } 09531 cmd = 't'; 09532 } else { 09533 switch (cmd) { 09534 case '1': 09535 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09536 break; 09537 case '2': 09538 DELETE(prefile, -1, prefile, vmu); 09539 ast_play_and_wait(chan, "vm-tempremoved"); 09540 cmd = 't'; 09541 break; 09542 case '*': 09543 cmd = 't'; 09544 break; 09545 default: 09546 cmd = ast_play_and_wait(chan, 09547 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09548 "vm-tempgreeting2" : "vm-tempgreeting"); 09549 if (!cmd) { 09550 cmd = ast_waitfordigit(chan, 6000); 09551 } 09552 if (!cmd) { 09553 retries++; 09554 } 09555 if (retries > 3) { 09556 cmd = 't'; 09557 } 09558 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09559 } 09560 } 09561 DISPOSE(prefile, -1); 09562 } 09563 if (cmd == 't') 09564 cmd = 0; 09565 return cmd; 09566 }
| static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 11450 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and vm_users_data_provider_get_helper().
11452 { 11453 struct ast_vm_user *user; 11454 11455 AST_LIST_LOCK(&users); 11456 AST_LIST_TRAVERSE(&users, user, list) { 11457 vm_users_data_provider_get_helper(search, data_root, user); 11458 } 11459 AST_LIST_UNLOCK(&users); 11460 11461 return 0; 11462 }
| 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 11403 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().
11405 { 11406 struct ast_data *data_user, *data_zone; 11407 struct ast_data *data_state; 11408 struct vm_zone *zone = NULL; 11409 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11410 char ext_context[256] = ""; 11411 11412 data_user = ast_data_add_node(data_root, "user"); 11413 if (!data_user) { 11414 return -1; 11415 } 11416 11417 ast_data_add_structure(ast_vm_user, data_user, user); 11418 11419 AST_LIST_LOCK(&zones); 11420 AST_LIST_TRAVERSE(&zones, zone, list) { 11421 if (!strcmp(zone->name, user->zonetag)) { 11422 break; 11423 } 11424 } 11425 AST_LIST_UNLOCK(&zones); 11426 11427 /* state */ 11428 data_state = ast_data_add_node(data_user, "state"); 11429 if (!data_state) { 11430 return -1; 11431 } 11432 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11433 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11434 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11435 ast_data_add_int(data_state, "newmsg", newmsg); 11436 ast_data_add_int(data_state, "oldmsg", oldmsg); 11437 11438 if (zone) { 11439 data_zone = ast_data_add_node(data_user, "zone"); 11440 ast_data_add_structure(vm_zone, data_zone, zone); 11441 } 11442 11443 if (!ast_data_search_match(search, data_user)) { 11444 ast_data_remove_node(data_root, data_user); 11445 } 11446 11447 return 0; 11448 }
| static int vmauthenticate | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 11089 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().
11090 { 11091 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11092 struct ast_vm_user vmus; 11093 char *options = NULL; 11094 int silent = 0, skipuser = 0; 11095 int res = -1; 11096 11097 if (data) { 11098 s = ast_strdupa(data); 11099 user = strsep(&s, ","); 11100 options = strsep(&s, ","); 11101 if (user) { 11102 s = user; 11103 user = strsep(&s, "@"); 11104 context = strsep(&s, ""); 11105 if (!ast_strlen_zero(user)) 11106 skipuser++; 11107 ast_copy_string(mailbox, user, sizeof(mailbox)); 11108 } 11109 } 11110 11111 if (options) { 11112 silent = (strchr(options, 's')) != NULL; 11113 } 11114 11115 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11116 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11117 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11118 ast_play_and_wait(chan, "auth-thankyou"); 11119 res = 0; 11120 } else if (mailbox[0] == '*') { 11121 /* user entered '*' */ 11122 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11123 res = 0; /* prevent hangup */ 11124 } 11125 } 11126 11127 return res; 11128 }
| static int vmsayname_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 12629 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().
12630 { 12631 char *context; 12632 char *args_copy; 12633 int res; 12634 12635 if (ast_strlen_zero(data)) { 12636 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n"); 12637 return -1; 12638 } 12639 12640 args_copy = ast_strdupa(data); 12641 if ((context = strchr(args_copy, '@'))) { 12642 *context++ = '\0'; 12643 } else { 12644 context = "default"; 12645 } 12646 12647 if ((res = sayname(chan, args_copy, context) < 0)) { 12648 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12649 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12650 if (!res) { 12651 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12652 } 12653 } 12654 12655 return res; 12656 }
| 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 7503 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().
07504 { 07505 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07506 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); 07507 }
| static int wait_file2 | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | file | |||
| ) | [static] |
Definition at line 7495 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().
07496 { 07497 int res; 07498 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07499 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07500 return res; 07501 }
| static int write_password_to_file | ( | const char * | secretfn, | |
| const char * | password | |||
| ) | [static] |
Definition at line 12596 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().
12596 { 12597 struct ast_config *conf; 12598 struct ast_category *cat; 12599 struct ast_variable *var; 12600 int res = -1; 12601 12602 if (!(conf = ast_config_new())) { 12603 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12604 return res; 12605 } 12606 if (!(cat = ast_category_new("general", "", 1))) { 12607 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12608 ast_config_destroy(conf); 12609 return res; 12610 } 12611 if (!(var = ast_variable_new("password", password, ""))) { 12612 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12613 ast_config_destroy(conf); 12614 ast_category_destroy(cat); 12615 return res; 12616 } 12617 ast_category_append(conf, cat); 12618 ast_variable_append(cat, var); 12619 if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12620 res = 0; 12621 } else { 12622 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12623 } 12624 12625 ast_config_destroy(conf); 12626 return res; 12627 }
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 11328 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 11084 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 11464 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