#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 | mwi_subs |
| struct | users |
| list of users found in the config file More... | |
| struct | vm_state |
| struct | vm_zone |
| struct | zones |
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 void | __fini_mwi_subs (void) |
| static int | __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit) |
| static void | __init_mwi_subs (void) |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | acf_mailbox_exists (struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len) |
| static int | acf_vm_info (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_DATA_STRUCTURE (vm_zone, DATA_EXPORT_VM_ZONES) | |
| AST_DATA_STRUCTURE (ast_vm_user, DATA_EXPORT_VM_USERS) | |
| 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, int saycidnumber) |
| 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 | 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 struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } |
| 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 struct ast_module_info * | ast_module_info = &__mod_info |
| static char | callcontext [AST_MAX_CONTEXT] = "" |
| static char | charset [32] = "ISO-8859-1" |
| static char | cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64] |
| static struct ast_cli_entry | cli_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 ast_mutex_t | poll_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } |
| 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_app_option | vm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'd' ] = { .flag = OPT_DTMFEXIT , .arg_index = OPT_ARG_DTMFEXIT + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 }, [ 'U' ] = { .flag = OPT_MESSAGE_Urgent }, [ 'P' ] = { .flag = OPT_MESSAGE_PRIORITY }} |
| static struct ast_data_entry | vm_data_providers [] |
| static struct ast_custom_function | vm_info_acf |
| 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] |
This module requires res_adsi to load. This needs to be optional during compilation.
This file is now almost impossible to work with, due to all #ifdefs. Feels like the database code before realtime. Someone - please come up with a plan to clean this up.
Definition in file app_voicemail.c.
| #define ASTERISK_USERNAME "asterisk" |
Definition at line 499 of file app_voicemail.c.
| #define BASELINELEN 72 |
| #define BASEMAXINLINE 256 |
| #define CHUNKSIZE 65536 |
Definition at line 496 of file app_voicemail.c.
| #define COMMAND_TIMEOUT 5000 |
Definition at line 492 of file app_voicemail.c.
| #define COPY | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h | ) | (copy_plain_file(g,h)); |
| #define DATA_EXPORT_VM_USERS | ( | USER | ) |
Definition at line 11492 of file app_voicemail.c.
| #define DATA_EXPORT_VM_ZONES | ( | ZONE | ) |
Value:
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 11520 of file app_voicemail.c.
| #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 |
By default, poll every 30 seconds
Definition at line 886 of file app_voicemail.c.
Referenced by actual_load_config().
| #define DELETE | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (vm_delete(c)) |
Definition at line 817 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 812 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 527 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 552 of file app_voicemail.c.
| #define EXISTS | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 814 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 515 of file app_voicemail.c.
Referenced by leave_voicemail(), play_record_review(), and vm_forwardoptions().
| #define MAX_DATETIME_FORMAT 512 |
Definition at line 530 of file app_voicemail.c.
| #define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 531 of file app_voicemail.c.
| #define MAXMSG 100 |
Definition at line 517 of file app_voicemail.c.
Referenced by actual_load_config(), and apply_option().
| #define MAXMSGLIMIT 9999 |
Definition at line 518 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 520 of file app_voicemail.c.
Referenced by actual_load_config().
| #define OPERATOR_EXIT 300 |
Definition at line 553 of file app_voicemail.c.
Referenced by leave_voicemail(), vm_exec(), and vm_execmain().
| #define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 829 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
| #define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 828 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 815 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 811 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 513 of file app_voicemail.c.
| #define SMDI_MWI_WAIT_TIMEOUT 1000 |
| #define STORE | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h, | |||||
| i, | |||||
| j | ) |
Definition at line 813 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 838 of file app_voicemail.c.
| #define VALID_DTMF "1234567890*#" |
| #define VM_ALLOCED (1 << 13) |
Structure was malloc'ed, instead of placed in a return (usually static) buffer
Definition at line 546 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 544 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 545 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 543 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 537 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 541 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 540 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 551 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 550 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 549 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 534 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 542 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 533 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 535 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 538 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 547 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 539 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 536 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 548 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 750 of file app_voicemail.c.
| #define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 498 of file app_voicemail.c.
| #define VOICEMAIL_DIR_MODE 0777 |
Definition at line 494 of file app_voicemail.c.
| #define VOICEMAIL_FILE_MODE 0666 |
Definition at line 495 of file app_voicemail.c.
Referenced by add_email_attachment(), copy(), leave_voicemail(), and vm_mkftemp().
| enum vm_box |
Definition at line 556 of file app_voicemail.c.
00556 { 00557 NEW_FOLDER, 00558 OLD_FOLDER, 00559 WORK_FOLDER, 00560 FAMILY_FOLDER, 00561 FRIENDS_FOLDER, 00562 GREETINGS_FOLDER 00563 };
| enum vm_option_args |
Definition at line 577 of file app_voicemail.c.
00577 { 00578 OPT_ARG_RECORDGAIN = 0, 00579 OPT_ARG_PLAYFOLDER = 1, 00580 OPT_ARG_DTMFEXIT = 2, 00581 /* This *must* be the last value in this enum! */ 00582 OPT_ARG_ARRAY_SIZE = 3, 00583 };
| 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 565 of file app_voicemail.c.
00565 { 00566 OPT_SILENT = (1 << 0), 00567 OPT_BUSY_GREETING = (1 << 1), 00568 OPT_UNAVAIL_GREETING = (1 << 2), 00569 OPT_RECORDGAIN = (1 << 3), 00570 OPT_PREPEND_MAILBOX = (1 << 4), 00571 OPT_AUTOPLAY = (1 << 6), 00572 OPT_DTMFEXIT = (1 << 7), 00573 OPT_MESSAGE_Urgent = (1 << 8), 00574 OPT_MESSAGE_PRIORITY = (1 << 9) 00575 };
| enum vm_passwordlocation |
Definition at line 585 of file app_voicemail.c.
00585 { 00586 OPT_PWLOC_VOICEMAILCONF = 0, 00587 OPT_PWLOC_SPOOLDIR = 1, 00588 OPT_PWLOC_USERSCONF = 2, 00589 };
| static void __fini_mwi_subs | ( | void | ) | [static] |
Definition at line 922 of file app_voicemail.c.
00941 : * 1. create a sound along the lines of "Please try again. When done, press the pound key" which could be spliced
| static int __has_voicemail | ( | const char * | context, | |
| const char * | mailbox, | |||
| const char * | folder, | |||
| int | shortcircuit | |||
| ) | [static] |
Definition at line 5474 of file app_voicemail.c.
References ast_strlen_zero().
Referenced by has_voicemail(), inboxcount2(), and messagecount().
05475 { 05476 DIR *dir; 05477 struct dirent *de; 05478 char fn[256]; 05479 int ret = 0; 05480 05481 /* If no mailbox, return immediately */ 05482 if (ast_strlen_zero(mailbox)) 05483 return 0; 05484 05485 if (ast_strlen_zero(folder)) 05486 folder = "INBOX"; 05487 if (ast_strlen_zero(context)) 05488 context = "default"; 05489 05490 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05491 05492 if (!(dir = opendir(fn))) 05493 return 0; 05494 05495 while ((de = readdir(dir))) { 05496 if (!strncasecmp(de->d_name, "msg", 3)) { 05497 if (shortcircuit) { 05498 ret = 1; 05499 break; 05500 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05501 ret++; 05502 } 05503 } 05504 } 05505 05506 closedir(dir); 05507 05508 return ret; 05509 }
| static void __init_mwi_subs | ( | void | ) | [static] |
Definition at line 922 of file app_voicemail.c.
00941 : * 1. create a sound along the lines of "Please try again. When done, press the pound key" which could be spliced
| static void __reg_module | ( | void | ) | [static] |
Definition at line 13910 of file app_voicemail.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 13910 of file app_voicemail.c.
| static int acf_mailbox_exists | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | args, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 11111 of file app_voicemail.c.
References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_WARNING, AST_NONSTANDARD_APP_ARGS, ast_strlen_zero(), find_user(), LOG_ERROR, and mbox().
11112 { 11113 struct ast_vm_user svm; 11114 AST_DECLARE_APP_ARGS(arg, 11115 AST_APP_ARG(mbox); 11116 AST_APP_ARG(context); 11117 ); 11118 static int dep_warning = 0; 11119 11120 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11121 11122 if (ast_strlen_zero(arg.mbox)) { 11123 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11124 return -1; 11125 } 11126 11127 if (!dep_warning) { 11128 dep_warning = 1; 11129 ast_log(AST_LOG_WARNING, "MAILBOX_EXISTS is deprecated. Please use ${VM_INFO(%s,exists)} instead.\n", args); 11130 } 11131 11132 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11133 return 0; 11134 }
| static int acf_vm_info | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | args, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 11136 of file app_voicemail.c.
References AST_APP_ARG, ast_channel_language(), ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_vm_user::email, find_user(), ast_vm_user::fullname, ast_vm_user::language, ast_vm_user::locale, LOG_ERROR, messagecount(), ast_vm_user::pager, parse(), ast_vm_user::password, S_OR, strsep(), and ast_vm_user::zonetag.
11137 { 11138 struct ast_vm_user *vmu = NULL; 11139 char *tmp, *mailbox, *context, *parse; 11140 int res = 0; 11141 11142 AST_DECLARE_APP_ARGS(arg, 11143 AST_APP_ARG(mailbox_context); 11144 AST_APP_ARG(attribute); 11145 AST_APP_ARG(folder); 11146 ); 11147 11148 buf[0] = '\0'; 11149 11150 if (ast_strlen_zero(args)) { 11151 ast_log(LOG_ERROR, "VM_INFO requires an argument (<mailbox>[@<context>],attribute[,folder])\n"); 11152 return -1; 11153 } 11154 11155 parse = ast_strdupa(args); 11156 AST_STANDARD_APP_ARGS(arg, parse); 11157 11158 if (ast_strlen_zero(arg.mailbox_context) || ast_strlen_zero(arg.attribute)) { 11159 ast_log(LOG_ERROR, "VM_INFO requires an argument (<mailbox>[@<context>],attribute[,folder])\n"); 11160 return -1; 11161 } 11162 11163 tmp = ast_strdupa(arg.mailbox_context); 11164 mailbox = strsep(&tmp, "@"); 11165 context = strsep(&tmp, ""); 11166 11167 if (ast_strlen_zero(context)) { 11168 context = "default"; 11169 } 11170 11171 vmu = find_user(NULL, context, mailbox); 11172 11173 if (!strncasecmp(arg.attribute, "exists", 5)) { 11174 ast_copy_string(buf, vmu ? "1" : "0", len); 11175 return 0; 11176 } 11177 11178 if (vmu) { 11179 if (!strncasecmp(arg.attribute, "password", 8)) { 11180 ast_copy_string(buf, vmu->password, len); 11181 } else if (!strncasecmp(arg.attribute, "fullname", 8)) { 11182 ast_copy_string(buf, vmu->fullname, len); 11183 } else if (!strncasecmp(arg.attribute, "email", 5)) { 11184 ast_copy_string(buf, vmu->email, len); 11185 } else if (!strncasecmp(arg.attribute, "pager", 5)) { 11186 ast_copy_string(buf, vmu->pager, len); 11187 } else if (!strncasecmp(arg.attribute, "language", 8)) { 11188 ast_copy_string(buf, S_OR(vmu->language, ast_channel_language(chan)), len); 11189 } else if (!strncasecmp(arg.attribute, "locale", 6)) { 11190 ast_copy_string(buf, vmu->locale, len); 11191 } else if (!strncasecmp(arg.attribute, "tz", 2)) { 11192 ast_copy_string(buf, vmu->zonetag, len); 11193 } else if (!strncasecmp(arg.attribute, "count", 5)) { 11194 /* If mbxfolder is empty messagecount will default to INBOX */ 11195 res = messagecount(context, mailbox, arg.folder); 11196 if (res < 0) { 11197 ast_log(LOG_ERROR, "Unable to retrieve message count for mailbox %s\n", arg.mailbox_context); 11198 return -1; 11199 } 11200 snprintf(buf, len, "%d", res); 11201 } else { 11202 ast_log(LOG_ERROR, "Unknown attribute '%s' for VM_INFO\n", arg.attribute); 11203 return -1; 11204 } 11205 } 11206 11207 return 0; 11208 }
| static int actual_load_config | ( | int | reload, | |
| struct ast_config * | cfg, | |||
| struct ast_config * | ucfg | |||
| ) | [static] |
Definition at line 12024 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_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, 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, LOG_ERROR, ast_vm_user::mailbox, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, MINPASSWORD, vm_zone::msg_format, vm_zone::name, 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, populate_defaults(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, read_password_from_file(), saydurationminfo, SENDMAIL, start_poll_thread(), stop_poll_thread(), strsep(), substitute_escapes(), THRESHOLD_SILENCE, vm_zone::timezone, 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_SVMAIL, and VM_TEMPGREETWARN.
Referenced by load_config().
12025 { 12026 struct ast_vm_user *current; 12027 char *cat; 12028 struct ast_variable *var; 12029 const char *val; 12030 char *q, *stringp, *tmp; 12031 int x; 12032 int tmpadsi[4]; 12033 char secretfn[PATH_MAX] = ""; 12034 12035 #ifdef IMAP_STORAGE 12036 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 12037 #endif 12038 /* set audio control prompts */ 12039 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 12040 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 12041 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 12042 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 12043 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 12044 12045 /* Free all the users structure */ 12046 free_vm_users(); 12047 12048 /* Free all the zones structure */ 12049 free_vm_zones(); 12050 12051 AST_LIST_LOCK(&users); 12052 12053 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 12054 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 12055 12056 if (cfg) { 12057 /* General settings */ 12058 12059 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 12060 val = "default"; 12061 ast_copy_string(userscontext, val, sizeof(userscontext)); 12062 /* Attach voice message to mail message ? */ 12063 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 12064 val = "yes"; 12065 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 12066 12067 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 12068 val = "no"; 12069 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 12070 12071 volgain = 0.0; 12072 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 12073 sscanf(val, "%30lf", &volgain); 12074 12075 #ifdef ODBC_STORAGE 12076 strcpy(odbc_database, "asterisk"); 12077 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 12078 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 12079 } 12080 strcpy(odbc_table, "voicemessages"); 12081 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 12082 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 12083 } 12084 #endif 12085 /* Mail command */ 12086 strcpy(mailcmd, SENDMAIL); 12087 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 12088 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 12089 12090 maxsilence = 0; 12091 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 12092 maxsilence = atoi(val); 12093 if (maxsilence > 0) 12094 maxsilence *= 1000; 12095 } 12096 12097 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 12098 maxmsg = MAXMSG; 12099 } else { 12100 maxmsg = atoi(val); 12101 if (maxmsg < 0) { 12102 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 12103 maxmsg = MAXMSG; 12104 } else if (maxmsg > MAXMSGLIMIT) { 12105 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 12106 maxmsg = MAXMSGLIMIT; 12107 } 12108 } 12109 12110 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 12111 maxdeletedmsg = 0; 12112 } else { 12113 if (sscanf(val, "%30d", &x) == 1) 12114 maxdeletedmsg = x; 12115 else if (ast_true(val)) 12116 maxdeletedmsg = MAXMSG; 12117 else 12118 maxdeletedmsg = 0; 12119 12120 if (maxdeletedmsg < 0) { 12121 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 12122 maxdeletedmsg = MAXMSG; 12123 } else if (maxdeletedmsg > MAXMSGLIMIT) { 12124 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 12125 maxdeletedmsg = MAXMSGLIMIT; 12126 } 12127 } 12128 12129 /* Load date format config for voicemail mail */ 12130 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 12131 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 12132 } 12133 12134 /* Load date format config for voicemail pager mail */ 12135 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 12136 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 12137 } 12138 12139 /* External password changing command */ 12140 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 12141 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12142 pwdchange = PWDCHANGE_EXTERNAL; 12143 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 12144 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12145 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 12146 } 12147 12148 /* External password validation command */ 12149 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 12150 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 12151 ast_debug(1, "found externpasscheck: %s\n", ext_pass_check_cmd); 12152 } 12153 12154 #ifdef IMAP_STORAGE 12155 /* IMAP server address */ 12156 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 12157 ast_copy_string(imapserver, val, sizeof(imapserver)); 12158 } else { 12159 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 12160 } 12161 /* IMAP server port */ 12162 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 12163 ast_copy_string(imapport, val, sizeof(imapport)); 12164 } else { 12165 ast_copy_string(imapport, "143", sizeof(imapport)); 12166 } 12167 /* IMAP server flags */ 12168 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 12169 ast_copy_string(imapflags, val, sizeof(imapflags)); 12170 } 12171 /* IMAP server master username */ 12172 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 12173 ast_copy_string(authuser, val, sizeof(authuser)); 12174 } 12175 /* IMAP server master password */ 12176 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 12177 ast_copy_string(authpassword, val, sizeof(authpassword)); 12178 } 12179 /* Expunge on exit */ 12180 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 12181 if (ast_false(val)) 12182 expungeonhangup = 0; 12183 else 12184 expungeonhangup = 1; 12185 } else { 12186 expungeonhangup = 1; 12187 } 12188 /* IMAP voicemail folder */ 12189 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 12190 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12191 } else { 12192 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12193 } 12194 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12195 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12196 } 12197 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12198 imapgreetings = ast_true(val); 12199 } else { 12200 imapgreetings = 0; 12201 } 12202 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12203 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12204 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12205 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12206 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12207 } else { 12208 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12209 } 12210 12211 /* There is some very unorthodox casting done here. This is due 12212 * to the way c-client handles the argument passed in. It expects a 12213 * void pointer and casts the pointer directly to a long without 12214 * first dereferencing it. */ 12215 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12216 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12217 } else { 12218 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12219 } 12220 12221 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12222 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12223 } else { 12224 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12225 } 12226 12227 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12228 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12229 } else { 12230 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12231 } 12232 12233 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12234 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12235 } else { 12236 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12237 } 12238 12239 /* Increment configuration version */ 12240 imapversion++; 12241 #endif 12242 /* External voicemail notify application */ 12243 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12244 ast_copy_string(externnotify, val, sizeof(externnotify)); 12245 ast_debug(1, "found externnotify: %s\n", externnotify); 12246 } else { 12247 externnotify[0] = '\0'; 12248 } 12249 12250 /* SMDI voicemail notification */ 12251 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12252 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12253 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12254 smdi_iface = ast_smdi_interface_find(val); 12255 } else { 12256 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12257 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12258 } 12259 if (!smdi_iface) { 12260 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12261 } 12262 } 12263 12264 /* Silence treshold */ 12265 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12266 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12267 silencethreshold = atoi(val); 12268 12269 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12270 val = ASTERISK_USERNAME; 12271 ast_copy_string(serveremail, val, sizeof(serveremail)); 12272 12273 vmmaxsecs = 0; 12274 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12275 if (sscanf(val, "%30d", &x) == 1) { 12276 vmmaxsecs = x; 12277 } else { 12278 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12279 } 12280 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12281 static int maxmessage_deprecate = 0; 12282 if (maxmessage_deprecate == 0) { 12283 maxmessage_deprecate = 1; 12284 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12285 } 12286 if (sscanf(val, "%30d", &x) == 1) { 12287 vmmaxsecs = x; 12288 } else { 12289 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12290 } 12291 } 12292 12293 vmminsecs = 0; 12294 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12295 if (sscanf(val, "%30d", &x) == 1) { 12296 vmminsecs = x; 12297 if (maxsilence / 1000 >= vmminsecs) { 12298 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12299 } 12300 } else { 12301 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12302 } 12303 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12304 static int maxmessage_deprecate = 0; 12305 if (maxmessage_deprecate == 0) { 12306 maxmessage_deprecate = 1; 12307 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12308 } 12309 if (sscanf(val, "%30d", &x) == 1) { 12310 vmminsecs = x; 12311 if (maxsilence / 1000 >= vmminsecs) { 12312 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12313 } 12314 } else { 12315 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12316 } 12317 } 12318 12319 val = ast_variable_retrieve(cfg, "general", "format"); 12320 if (!val) { 12321 val = "wav"; 12322 } else { 12323 tmp = ast_strdupa(val); 12324 val = ast_format_str_reduce(tmp); 12325 if (!val) { 12326 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12327 val = "wav"; 12328 } 12329 } 12330 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12331 12332 skipms = 3000; 12333 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12334 if (sscanf(val, "%30d", &x) == 1) { 12335 maxgreet = x; 12336 } else { 12337 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12338 } 12339 } 12340 12341 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12342 if (sscanf(val, "%30d", &x) == 1) { 12343 skipms = x; 12344 } else { 12345 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12346 } 12347 } 12348 12349 maxlogins = 3; 12350 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12351 if (sscanf(val, "%30d", &x) == 1) { 12352 maxlogins = x; 12353 } else { 12354 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12355 } 12356 } 12357 12358 minpassword = MINPASSWORD; 12359 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12360 if (sscanf(val, "%30d", &x) == 1) { 12361 minpassword = x; 12362 } else { 12363 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12364 } 12365 } 12366 12367 /* Force new user to record name ? */ 12368 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12369 val = "no"; 12370 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12371 12372 /* Force new user to record greetings ? */ 12373 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12374 val = "no"; 12375 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12376 12377 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12378 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12379 stringp = ast_strdupa(val); 12380 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12381 if (!ast_strlen_zero(stringp)) { 12382 q = strsep(&stringp, ","); 12383 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12384 q++; 12385 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12386 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12387 } else { 12388 cidinternalcontexts[x][0] = '\0'; 12389 } 12390 } 12391 } 12392 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12393 ast_debug(1, "VM Review Option disabled globally\n"); 12394 val = "no"; 12395 } 12396 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12397 12398 /* Temporary greeting reminder */ 12399 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12400 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12401 val = "no"; 12402 } else { 12403 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12404 } 12405 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12406 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12407 ast_debug(1, "VM next message wrap disabled globally\n"); 12408 val = "no"; 12409 } 12410 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12411 12412 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12413 ast_debug(1, "VM Operator break disabled globally\n"); 12414 val = "no"; 12415 } 12416 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12417 12418 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12419 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12420 val = "no"; 12421 } 12422 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12423 12424 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12425 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12426 val = "no"; 12427 } 12428 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12429 12430 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12431 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12432 val = "yes"; 12433 } 12434 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12435 12436 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12437 ast_debug(1, "Move Heard enabled globally\n"); 12438 val = "yes"; 12439 } 12440 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12441 12442 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12443 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12444 val = "no"; 12445 } 12446 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12447 12448 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12449 ast_debug(1, "Duration info before msg enabled globally\n"); 12450 val = "yes"; 12451 } 12452 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12453 12454 saydurationminfo = 2; 12455 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12456 if (sscanf(val, "%30d", &x) == 1) { 12457 saydurationminfo = x; 12458 } else { 12459 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12460 } 12461 } 12462 12463 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12464 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12465 val = "no"; 12466 } 12467 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12468 12469 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12470 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12471 ast_debug(1, "found dialout context: %s\n", dialcontext); 12472 } else { 12473 dialcontext[0] = '\0'; 12474 } 12475 12476 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12477 ast_copy_string(callcontext, val, sizeof(callcontext)); 12478 ast_debug(1, "found callback context: %s\n", callcontext); 12479 } else { 12480 callcontext[0] = '\0'; 12481 } 12482 12483 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12484 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12485 ast_debug(1, "found operator context: %s\n", exitcontext); 12486 } else { 12487 exitcontext[0] = '\0'; 12488 } 12489 12490 /* load password sounds configuration */ 12491 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12492 ast_copy_string(vm_password, val, sizeof(vm_password)); 12493 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12494 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12495 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12496 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12497 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12498 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12499 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12500 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12501 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12502 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12503 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12504 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12505 } 12506 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12507 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12508 } 12509 /* load configurable audio prompts */ 12510 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12511 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12512 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12513 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12514 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12515 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12516 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12517 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12518 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12519 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12520 12521 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12522 val = "no"; 12523 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12524 12525 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12526 val = "voicemail.conf"; 12527 } 12528 if (!(strcmp(val, "spooldir"))) { 12529 passwordlocation = OPT_PWLOC_SPOOLDIR; 12530 } else { 12531 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12532 } 12533 12534 poll_freq = DEFAULT_POLL_FREQ; 12535 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12536 if (sscanf(val, "%30u", &poll_freq) != 1) { 12537 poll_freq = DEFAULT_POLL_FREQ; 12538 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12539 } 12540 } 12541 12542 poll_mailboxes = 0; 12543 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12544 poll_mailboxes = ast_true(val); 12545 12546 memset(fromstring, 0, sizeof(fromstring)); 12547 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12548 strcpy(charset, "ISO-8859-1"); 12549 if (emailbody) { 12550 ast_free(emailbody); 12551 emailbody = NULL; 12552 } 12553 if (emailsubject) { 12554 ast_free(emailsubject); 12555 emailsubject = NULL; 12556 } 12557 if (pagerbody) { 12558 ast_free(pagerbody); 12559 pagerbody = NULL; 12560 } 12561 if (pagersubject) { 12562 ast_free(pagersubject); 12563 pagersubject = NULL; 12564 } 12565 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12566 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12567 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12568 ast_copy_string(fromstring, val, sizeof(fromstring)); 12569 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12570 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12571 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12572 ast_copy_string(charset, val, sizeof(charset)); 12573 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12574 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12575 for (x = 0; x < 4; x++) { 12576 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12577 } 12578 } 12579 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12580 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12581 for (x = 0; x < 4; x++) { 12582 memcpy(&adsisec[x], &tmpadsi[x], 1); 12583 } 12584 } 12585 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12586 if (atoi(val)) { 12587 adsiver = atoi(val); 12588 } 12589 } 12590 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12591 ast_copy_string(zonetag, val, sizeof(zonetag)); 12592 } 12593 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12594 ast_copy_string(locale, val, sizeof(locale)); 12595 } 12596 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12597 emailsubject = ast_strdup(substitute_escapes(val)); 12598 } 12599 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12600 emailbody = ast_strdup(substitute_escapes(val)); 12601 } 12602 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12603 pagersubject = ast_strdup(substitute_escapes(val)); 12604 } 12605 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12606 pagerbody = ast_strdup(substitute_escapes(val)); 12607 } 12608 12609 /* load mailboxes from users.conf */ 12610 if (ucfg) { 12611 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12612 if (!strcasecmp(cat, "general")) { 12613 continue; 12614 } 12615 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12616 continue; 12617 if ((current = find_or_create(userscontext, cat))) { 12618 populate_defaults(current); 12619 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12620 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12621 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12622 current->passwordlocation = OPT_PWLOC_USERSCONF; 12623 } 12624 12625 switch (current->passwordlocation) { 12626 case OPT_PWLOC_SPOOLDIR: 12627 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12628 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12629 } 12630 } 12631 } 12632 } 12633 12634 /* load mailboxes from voicemail.conf */ 12635 cat = ast_category_browse(cfg, NULL); 12636 while (cat) { 12637 if (strcasecmp(cat, "general")) { 12638 var = ast_variable_browse(cfg, cat); 12639 if (strcasecmp(cat, "zonemessages")) { 12640 /* Process mailboxes in this context */ 12641 while (var) { 12642 append_mailbox(cat, var->name, var->value); 12643 var = var->next; 12644 } 12645 } else { 12646 /* Timezones in this context */ 12647 while (var) { 12648 struct vm_zone *z; 12649 if ((z = ast_malloc(sizeof(*z)))) { 12650 char *msg_format, *tzone; 12651 msg_format = ast_strdupa(var->value); 12652 tzone = strsep(&msg_format, "|,"); 12653 if (msg_format) { 12654 ast_copy_string(z->name, var->name, sizeof(z->name)); 12655 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12656 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12657 AST_LIST_LOCK(&zones); 12658 AST_LIST_INSERT_HEAD(&zones, z, list); 12659 AST_LIST_UNLOCK(&zones); 12660 } else { 12661 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12662 ast_free(z); 12663 } 12664 } else { 12665 AST_LIST_UNLOCK(&users); 12666 return -1; 12667 } 12668 var = var->next; 12669 } 12670 } 12671 } 12672 cat = ast_category_browse(cfg, cat); 12673 } 12674 12675 AST_LIST_UNLOCK(&users); 12676 12677 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12678 start_poll_thread(); 12679 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12680 stop_poll_thread();; 12681 12682 return 0; 12683 } else { 12684 AST_LIST_UNLOCK(&users); 12685 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12686 return 0; 12687 } 12688 }
| 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 4884 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, VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.
Referenced by make_email_file().
04885 { 04886 char tmpdir[256], newtmp[256]; 04887 char fname[256]; 04888 char tmpcmd[256]; 04889 int tmpfd = -1; 04890 int soxstatus = 0; 04891 04892 /* Eww. We want formats to tell us their own MIME type */ 04893 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04894 04895 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04896 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04897 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04898 tmpfd = mkstemp(newtmp); 04899 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04900 ast_debug(3, "newtmp: %s\n", newtmp); 04901 if (tmpfd > -1) { 04902 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04903 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04904 attach = newtmp; 04905 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04906 } else { 04907 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04908 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04909 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04910 } 04911 } 04912 } 04913 fprintf(p, "--%s" ENDL, bound); 04914 if (msgnum > -1) 04915 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04916 else 04917 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04918 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04919 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04920 if (msgnum > -1) 04921 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04922 else 04923 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04924 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04925 base_encode(fname, p); 04926 if (last) 04927 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04928 if (tmpfd > -1) { 04929 if (soxstatus == 0) { 04930 unlink(fname); 04931 } 04932 close(tmpfd); 04933 unlink(newtmp); 04934 } 04935 return 0; 04936 }
| static void adsi_begin | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 6491 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().
06492 { 06493 int x; 06494 if (!ast_adsi_available(chan)) 06495 return; 06496 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06497 if (x < 0) 06498 return; 06499 if (!x) { 06500 if (adsi_load_vmail(chan, useadsi)) { 06501 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06502 return; 06503 } 06504 } else 06505 *useadsi = 1; 06506 }
| static void adsi_delete | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6680 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(), vm_state::curmsg, vm_state::deleted, and vm_state::lastmsg.
Referenced by vm_execmain().
06681 { 06682 int bytes = 0; 06683 unsigned char buf[256]; 06684 unsigned char keys[8]; 06685 06686 int x; 06687 06688 if (!ast_adsi_available(chan)) 06689 return; 06690 06691 /* New meaning for keys */ 06692 for (x = 0; x < 5; x++) 06693 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06694 06695 keys[6] = 0x0; 06696 keys[7] = 0x0; 06697 06698 if (!vms->curmsg) { 06699 /* No prev key, provide "Folder" instead */ 06700 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06701 } 06702 if (vms->curmsg >= vms->lastmsg) { 06703 /* If last message ... */ 06704 if (vms->curmsg) { 06705 /* but not only message, provide "Folder" instead */ 06706 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06707 } else { 06708 /* Otherwise if only message, leave blank */ 06709 keys[3] = 1; 06710 } 06711 } 06712 06713 /* If deleted, show "undeleted" */ 06714 if (vms->deleted[vms->curmsg]) 06715 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06716 06717 /* Except "Exit" */ 06718 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06719 bytes += ast_adsi_set_keys(buf + bytes, keys); 06720 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06721 06722 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06723 }
| static void adsi_folders | ( | struct ast_channel * | chan, | |
| int | start, | |||
| char * | label | |||
| ) | [static] |
Definition at line 6556 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().
06557 { 06558 unsigned char buf[256]; 06559 int bytes = 0; 06560 unsigned char keys[8]; 06561 int x, y; 06562 06563 if (!ast_adsi_available(chan)) 06564 return; 06565 06566 for (x = 0; x < 5; x++) { 06567 y = ADSI_KEY_APPS + 12 + start + x; 06568 if (y > ADSI_KEY_APPS + 12 + 4) 06569 y = 0; 06570 keys[x] = ADSI_KEY_SKT | y; 06571 } 06572 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06573 keys[6] = 0; 06574 keys[7] = 0; 06575 06576 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06577 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06578 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06579 bytes += ast_adsi_set_keys(buf + bytes, keys); 06580 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06581 06582 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06583 }
| static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6828 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().
06829 { 06830 unsigned char buf[256]; 06831 int bytes = 0; 06832 06833 if (!ast_adsi_available(chan)) 06834 return; 06835 bytes += adsi_logo(buf + bytes); 06836 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06837 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06838 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06839 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06840 06841 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06842 }
| static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 6362 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, 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().
06363 { 06364 unsigned char buf[256]; 06365 int bytes = 0; 06366 int x; 06367 char num[5]; 06368 06369 *useadsi = 0; 06370 bytes += ast_adsi_data_mode(buf + bytes); 06371 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06372 06373 bytes = 0; 06374 bytes += adsi_logo(buf); 06375 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06376 #ifdef DISPLAY 06377 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06378 #endif 06379 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06380 bytes += ast_adsi_data_mode(buf + bytes); 06381 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06382 06383 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06384 bytes = 0; 06385 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06386 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06387 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06388 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06389 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06390 return 0; 06391 } 06392 06393 #ifdef DISPLAY 06394 /* Add a dot */ 06395 bytes = 0; 06396 bytes += ast_adsi_logo(buf); 06397 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06398 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06399 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06400 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06401 #endif 06402 bytes = 0; 06403 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06404 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06405 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06406 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06407 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06408 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06409 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06410 06411 #ifdef DISPLAY 06412 /* Add another dot */ 06413 bytes = 0; 06414 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06415 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06416 06417 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06418 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06419 #endif 06420 06421 bytes = 0; 06422 /* These buttons we load but don't use yet */ 06423 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06424 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06425 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06426 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06427 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06428 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06429 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06430 06431 #ifdef DISPLAY 06432 /* Add another dot */ 06433 bytes = 0; 06434 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06435 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06436 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06437 #endif 06438 06439 bytes = 0; 06440 for (x = 0; x < 5; x++) { 06441 snprintf(num, sizeof(num), "%d", x); 06442 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06443 } 06444 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06445 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06446 06447 #ifdef DISPLAY 06448 /* Add another dot */ 06449 bytes = 0; 06450 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06451 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06452 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06453 #endif 06454 06455 if (ast_adsi_end_download(chan)) { 06456 bytes = 0; 06457 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06458 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06459 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06460 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06461 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06462 return 0; 06463 } 06464 bytes = 0; 06465 bytes += ast_adsi_download_disconnect(buf + bytes); 06466 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06467 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06468 06469 ast_debug(1, "Done downloading scripts...\n"); 06470 06471 #ifdef DISPLAY 06472 /* Add last dot */ 06473 bytes = 0; 06474 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06475 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06476 #endif 06477 ast_debug(1, "Restarting session...\n"); 06478 06479 bytes = 0; 06480 /* Load the session now */ 06481 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06482 *useadsi = 1; 06483 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06484 } else 06485 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06486 06487 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06488 return 0; 06489 }
| static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6508 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().
06509 { 06510 unsigned char buf[256]; 06511 int bytes = 0; 06512 unsigned char keys[8]; 06513 int x; 06514 if (!ast_adsi_available(chan)) 06515 return; 06516 06517 for (x = 0; x < 8; x++) 06518 keys[x] = 0; 06519 /* Set one key for next */ 06520 keys[3] = ADSI_KEY_APPS + 3; 06521 06522 bytes += adsi_logo(buf + bytes); 06523 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06524 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06525 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06526 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06527 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06528 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06529 bytes += ast_adsi_set_keys(buf + bytes, keys); 06530 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06531 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06532 }
| static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6354 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().
06355 { 06356 int bytes = 0; 06357 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06358 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06359 return bytes; 06360 }
| static void adsi_message | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6585 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_strlen_zero(), buf1, buf2, vm_state::curbox, vm_state::curmsg, vm_state::deleted, vm_state::fn, vm_state::lastmsg, and strsep().
Referenced by play_message(), and vm_execmain().
06586 { 06587 int bytes = 0; 06588 unsigned char buf[256]; 06589 char buf1[256], buf2[256]; 06590 char fn2[PATH_MAX]; 06591 06592 char cid[256] = ""; 06593 char *val; 06594 char *name, *num; 06595 char datetime[21] = ""; 06596 FILE *f; 06597 06598 unsigned char keys[8]; 06599 06600 int x; 06601 06602 if (!ast_adsi_available(chan)) 06603 return; 06604 06605 /* Retrieve important info */ 06606 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06607 f = fopen(fn2, "r"); 06608 if (f) { 06609 while (!feof(f)) { 06610 if (!fgets((char *) buf, sizeof(buf), f)) { 06611 continue; 06612 } 06613 if (!feof(f)) { 06614 char *stringp = NULL; 06615 stringp = (char *) buf; 06616 strsep(&stringp, "="); 06617 val = strsep(&stringp, "="); 06618 if (!ast_strlen_zero(val)) { 06619 if (!strcmp((char *) buf, "callerid")) 06620 ast_copy_string(cid, val, sizeof(cid)); 06621 if (!strcmp((char *) buf, "origdate")) 06622 ast_copy_string(datetime, val, sizeof(datetime)); 06623 } 06624 } 06625 } 06626 fclose(f); 06627 } 06628 /* New meaning for keys */ 06629 for (x = 0; x < 5; x++) 06630 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06631 keys[6] = 0x0; 06632 keys[7] = 0x0; 06633 06634 if (!vms->curmsg) { 06635 /* No prev key, provide "Folder" instead */ 06636 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06637 } 06638 if (vms->curmsg >= vms->lastmsg) { 06639 /* If last message ... */ 06640 if (vms->curmsg) { 06641 /* but not only message, provide "Folder" instead */ 06642 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06643 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06644 06645 } else { 06646 /* Otherwise if only message, leave blank */ 06647 keys[3] = 1; 06648 } 06649 } 06650 06651 if (!ast_strlen_zero(cid)) { 06652 ast_callerid_parse(cid, &name, &num); 06653 if (!name) 06654 name = num; 06655 } else 06656 name = "Unknown Caller"; 06657 06658 /* If deleted, show "undeleted" */ 06659 06660 if (vms->deleted[vms->curmsg]) 06661 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06662 06663 /* Except "Exit" */ 06664 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06665 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06666 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06667 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06668 06669 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06670 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06671 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06672 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06673 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06674 bytes += ast_adsi_set_keys(buf + bytes, keys); 06675 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06676 06677 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06678 }
| static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6534 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().
06535 { 06536 unsigned char buf[256]; 06537 int bytes = 0; 06538 unsigned char keys[8]; 06539 int x; 06540 if (!ast_adsi_available(chan)) 06541 return; 06542 06543 for (x = 0; x < 8; x++) 06544 keys[x] = 0; 06545 /* Set one key for next */ 06546 keys[3] = ADSI_KEY_APPS + 3; 06547 06548 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06549 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06550 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06551 bytes += ast_adsi_set_keys(buf + bytes, keys); 06552 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06553 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06554 }
| static void adsi_status | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6725 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(), buf1, buf2, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_execmain().
06726 { 06727 unsigned char buf[256] = ""; 06728 char buf1[256] = "", buf2[256] = ""; 06729 int bytes = 0; 06730 unsigned char keys[8]; 06731 int x; 06732 06733 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06734 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06735 if (!ast_adsi_available(chan)) 06736 return; 06737 if (vms->newmessages) { 06738 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06739 if (vms->oldmessages) { 06740 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06741 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06742 } else { 06743 snprintf(buf2, sizeof(buf2), "%s.", newm); 06744 } 06745 } else if (vms->oldmessages) { 06746 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06747 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06748 } else { 06749 strcpy(buf1, "You have no messages."); 06750 buf2[0] = ' '; 06751 buf2[1] = '\0'; 06752 } 06753 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06754 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06755 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06756 06757 for (x = 0; x < 6; x++) 06758 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06759 keys[6] = 0; 06760 keys[7] = 0; 06761 06762 /* Don't let them listen if there are none */ 06763 if (vms->lastmsg < 0) 06764 keys[0] = 1; 06765 bytes += ast_adsi_set_keys(buf + bytes, keys); 06766 06767 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06768 06769 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06770 }
| static void adsi_status2 | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6772 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(), buf1, buf2, vm_state::curbox, and vm_state::lastmsg.
Referenced by vm_execmain().
06773 { 06774 unsigned char buf[256] = ""; 06775 char buf1[256] = "", buf2[256] = ""; 06776 int bytes = 0; 06777 unsigned char keys[8]; 06778 int x; 06779 06780 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06781 06782 if (!ast_adsi_available(chan)) 06783 return; 06784 06785 /* Original command keys */ 06786 for (x = 0; x < 6; x++) 06787 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06788 06789 keys[6] = 0; 06790 keys[7] = 0; 06791 06792 if ((vms->lastmsg + 1) < 1) 06793 keys[0] = 0; 06794 06795 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06796 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06797 06798 if (vms->lastmsg + 1) 06799 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06800 else 06801 strcpy(buf2, "no messages."); 06802 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06803 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06804 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06805 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06806 bytes += ast_adsi_set_keys(buf + bytes, keys); 06807 06808 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06809 06810 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06811 06812 }
| 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 13470 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, CONFIG_STATUS_FILEINVALID, 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(), play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, and wait_file().
Referenced by vm_execmain().
13471 { 13472 int res = 0; 13473 char filename[PATH_MAX]; 13474 struct ast_config *msg_cfg = NULL; 13475 const char *origtime, *context; 13476 char *name, *num; 13477 int retries = 0; 13478 char *cid; 13479 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13480 13481 vms->starting = 0; 13482 13483 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13484 13485 /* Retrieve info from VM attribute file */ 13486 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13487 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13488 msg_cfg = ast_config_load(filename, config_flags); 13489 DISPOSE(vms->curdir, vms->curmsg); 13490 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 13491 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13492 return 0; 13493 } 13494 13495 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13496 ast_config_destroy(msg_cfg); 13497 return 0; 13498 } 13499 13500 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13501 13502 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13503 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13504 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13505 switch (option) { 13506 case 3: /* Play message envelope */ 13507 if (!res) { 13508 res = play_message_datetime(chan, vmu, origtime, filename); 13509 } 13510 if (!res) { 13511 res = play_message_callerid(chan, vms, cid, context, 0, 1); 13512 } 13513 13514 res = 't'; 13515 break; 13516 13517 case 2: /* Call back */ 13518 13519 if (ast_strlen_zero(cid)) 13520 break; 13521 13522 ast_callerid_parse(cid, &name, &num); 13523 while ((res > -1) && (res != 't')) { 13524 switch (res) { 13525 case '1': 13526 if (num) { 13527 /* Dial the CID number */ 13528 res = dialout(chan, vmu, num, vmu->callback); 13529 if (res) { 13530 ast_config_destroy(msg_cfg); 13531 return 9; 13532 } 13533 } else { 13534 res = '2'; 13535 } 13536 break; 13537 13538 case '2': 13539 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13540 if (!ast_strlen_zero(vmu->dialout)) { 13541 res = dialout(chan, vmu, NULL, vmu->dialout); 13542 if (res) { 13543 ast_config_destroy(msg_cfg); 13544 return 9; 13545 } 13546 } else { 13547 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13548 res = ast_play_and_wait(chan, "vm-sorry"); 13549 } 13550 ast_config_destroy(msg_cfg); 13551 return res; 13552 case '*': 13553 res = 't'; 13554 break; 13555 case '3': 13556 case '4': 13557 case '5': 13558 case '6': 13559 case '7': 13560 case '8': 13561 case '9': 13562 case '0': 13563 13564 res = ast_play_and_wait(chan, "vm-sorry"); 13565 retries++; 13566 break; 13567 default: 13568 if (num) { 13569 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13570 res = ast_play_and_wait(chan, "vm-num-i-have"); 13571 if (!res) 13572 res = play_message_callerid(chan, vms, num, vmu->context, 1, 1); 13573 if (!res) 13574 res = ast_play_and_wait(chan, "vm-tocallnum"); 13575 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13576 if (!ast_strlen_zero(vmu->dialout)) { 13577 if (!res) 13578 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13579 } 13580 } else { 13581 res = ast_play_and_wait(chan, "vm-nonumber"); 13582 if (!ast_strlen_zero(vmu->dialout)) { 13583 if (!res) 13584 res = ast_play_and_wait(chan, "vm-toenternumber"); 13585 } 13586 } 13587 if (!res) { 13588 res = ast_play_and_wait(chan, "vm-star-cancel"); 13589 } 13590 if (!res) { 13591 res = ast_waitfordigit(chan, 6000); 13592 } 13593 if (!res) { 13594 retries++; 13595 if (retries > 3) { 13596 res = 't'; 13597 } 13598 } 13599 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13600 break; 13601 13602 } 13603 if (res == 't') 13604 res = 0; 13605 else if (res == '*') 13606 res = -1; 13607 } 13608 break; 13609 13610 case 1: /* Reply */ 13611 /* Send reply directly to sender */ 13612 if (ast_strlen_zero(cid)) 13613 break; 13614 13615 ast_callerid_parse(cid, &name, &num); 13616 if (!num) { 13617 ast_verb(3, "No CID number available, no reply sent\n"); 13618 if (!res) 13619 res = ast_play_and_wait(chan, "vm-nonumber"); 13620 ast_config_destroy(msg_cfg); 13621 return res; 13622 } else { 13623 struct ast_vm_user vmu2; 13624 if (find_user(&vmu2, vmu->context, num)) { 13625 struct leave_vm_options leave_options; 13626 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13627 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13628 13629 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13630 13631 memset(&leave_options, 0, sizeof(leave_options)); 13632 leave_options.record_gain = record_gain; 13633 res = leave_voicemail(chan, mailbox, &leave_options); 13634 if (!res) 13635 res = 't'; 13636 ast_config_destroy(msg_cfg); 13637 return res; 13638 } else { 13639 /* Sender has no mailbox, can't reply */ 13640 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13641 ast_play_and_wait(chan, "vm-nobox"); 13642 res = 't'; 13643 ast_config_destroy(msg_cfg); 13644 return res; 13645 } 13646 } 13647 res = 0; 13648 13649 break; 13650 } 13651 13652 #ifndef IMAP_STORAGE 13653 ast_config_destroy(msg_cfg); 13654 13655 if (!res) { 13656 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13657 vms->heard[msg] = 1; 13658 res = wait_file(chan, vms, vms->fn); 13659 } 13660 #endif 13661 return res; 13662 }
| static int append_mailbox | ( | const char * | context, | |
| const char * | box, | |||
| const char * | data | |||
| ) | [static] |
Definition at line 10826 of file app_voicemail.c.
References apply_options(), 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 strsep().
Referenced by actual_load_config().
10827 { 10828 /* Assumes lock is already held */ 10829 char *tmp; 10830 char *stringp; 10831 char *s; 10832 struct ast_vm_user *vmu; 10833 char *mailbox_full; 10834 int new = 0, old = 0, urgent = 0; 10835 char secretfn[PATH_MAX] = ""; 10836 10837 tmp = ast_strdupa(data); 10838 10839 if (!(vmu = find_or_create(context, box))) 10840 return -1; 10841 10842 populate_defaults(vmu); 10843 10844 stringp = tmp; 10845 if ((s = strsep(&stringp, ","))) { 10846 if (!ast_strlen_zero(s) && s[0] == '*') { 10847 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10848 "\n\tmust be reset in voicemail.conf.\n", box); 10849 } 10850 /* assign password regardless of validity to prevent NULL password from being assigned */ 10851 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10852 } 10853 if (stringp && (s = strsep(&stringp, ","))) { 10854 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10855 } 10856 if (stringp && (s = strsep(&stringp, ","))) { 10857 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10858 } 10859 if (stringp && (s = strsep(&stringp, ","))) { 10860 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10861 } 10862 if (stringp && (s = strsep(&stringp, ","))) { 10863 apply_options(vmu, s); 10864 } 10865 10866 switch (vmu->passwordlocation) { 10867 case OPT_PWLOC_SPOOLDIR: 10868 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10869 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10870 } 10871 10872 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 10873 strcpy(mailbox_full, box); 10874 strcat(mailbox_full, "@"); 10875 strcat(mailbox_full, context); 10876 10877 inboxcount2(mailbox_full, &urgent, &new, &old); 10878 queue_mwi_event(mailbox_full, urgent, new, old); 10879 10880 return 0; 10881 }
| 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. |
Definition at line 1133 of file app_voicemail.c.
References apply_options(), ast_copy_string(), ast_free, 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, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by apply_options(), and apply_options_full().
01134 { 01135 int x; 01136 if (!strcasecmp(var, "attach")) { 01137 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01138 } else if (!strcasecmp(var, "attachfmt")) { 01139 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01140 } else if (!strcasecmp(var, "serveremail")) { 01141 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01142 } else if (!strcasecmp(var, "emailbody")) { 01143 ast_free(vmu->emailbody); 01144 vmu->emailbody = ast_strdup(substitute_escapes(value)); 01145 } else if (!strcasecmp(var, "emailsubject")) { 01146 ast_free(vmu->emailsubject); 01147 vmu->emailsubject = ast_strdup(substitute_escapes(value)); 01148 } else if (!strcasecmp(var, "language")) { 01149 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01150 } else if (!strcasecmp(var, "tz")) { 01151 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01152 } else if (!strcasecmp(var, "locale")) { 01153 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01154 #ifdef IMAP_STORAGE 01155 } else if (!strcasecmp(var, "imapuser")) { 01156 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01157 vmu->imapversion = imapversion; 01158 } else if (!strcasecmp(var, "imapserver")) { 01159 ast_copy_string(vmu->imapserver, value, sizeof(vmu->imapserver)); 01160 vmu->imapversion = imapversion; 01161 } else if (!strcasecmp(var, "imapport")) { 01162 ast_copy_string(vmu->imapport, value, sizeof(vmu->imapport)); 01163 vmu->imapversion = imapversion; 01164 } else if (!strcasecmp(var, "imapflags")) { 01165 ast_copy_string(vmu->imapflags, value, sizeof(vmu->imapflags)); 01166 vmu->imapversion = imapversion; 01167 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01168 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01169 vmu->imapversion = imapversion; 01170 } else if (!strcasecmp(var, "imapfolder")) { 01171 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01172 vmu->imapversion = imapversion; 01173 } else if (!strcasecmp(var, "imapvmshareid")) { 01174 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01175 vmu->imapversion = imapversion; 01176 #endif 01177 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01178 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01179 } else if (!strcasecmp(var, "saycid")){ 01180 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01181 } else if (!strcasecmp(var, "sendvoicemail")){ 01182 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01183 } else if (!strcasecmp(var, "review")){ 01184 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01185 } else if (!strcasecmp(var, "tempgreetwarn")){ 01186 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01187 } else if (!strcasecmp(var, "messagewrap")){ 01188 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01189 } else if (!strcasecmp(var, "operator")) { 01190 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01191 } else if (!strcasecmp(var, "envelope")){ 01192 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01193 } else if (!strcasecmp(var, "moveheard")){ 01194 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01195 } else if (!strcasecmp(var, "sayduration")){ 01196 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01197 } else if (!strcasecmp(var, "saydurationm")){ 01198 if (sscanf(value, "%30d", &x) == 1) { 01199 vmu->saydurationm = x; 01200 } else { 01201 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01202 } 01203 } else if (!strcasecmp(var, "forcename")){ 01204 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01205 } else if (!strcasecmp(var, "forcegreetings")){ 01206 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01207 } else if (!strcasecmp(var, "callback")) { 01208 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01209 } else if (!strcasecmp(var, "dialout")) { 01210 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01211 } else if (!strcasecmp(var, "exitcontext")) { 01212 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01213 } else if (!strcasecmp(var, "minsecs")) { 01214 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01215 vmu->minsecs = x; 01216 } else { 01217 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01218 vmu->minsecs = vmminsecs; 01219 } 01220 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01221 vmu->maxsecs = atoi(value); 01222 if (vmu->maxsecs <= 0) { 01223 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01224 vmu->maxsecs = vmmaxsecs; 01225 } else { 01226 vmu->maxsecs = atoi(value); 01227 } 01228 if (!strcasecmp(var, "maxmessage")) 01229 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01230 } else if (!strcasecmp(var, "maxmsg")) { 01231 vmu->maxmsg = atoi(value); 01232 /* Accept maxmsg=0 (Greetings only voicemail) */ 01233 if (vmu->maxmsg < 0) { 01234 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01235 vmu->maxmsg = MAXMSG; 01236 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01237 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01238 vmu->maxmsg = MAXMSGLIMIT; 01239 } 01240 } else if (!strcasecmp(var, "nextaftercmd")) { 01241 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01242 } else if (!strcasecmp(var, "backupdeleted")) { 01243 if (sscanf(value, "%30d", &x) == 1) 01244 vmu->maxdeletedmsg = x; 01245 else if (ast_true(value)) 01246 vmu->maxdeletedmsg = MAXMSG; 01247 else 01248 vmu->maxdeletedmsg = 0; 01249 01250 if (vmu->maxdeletedmsg < 0) { 01251 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01252 vmu->maxdeletedmsg = MAXMSG; 01253 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01254 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01255 vmu->maxdeletedmsg = MAXMSGLIMIT; 01256 } 01257 } else if (!strcasecmp(var, "volgain")) { 01258 sscanf(value, "%30lf", &vmu->volgain); 01259 } else if (!strcasecmp(var, "passwordlocation")) { 01260 if (!strcasecmp(value, "spooldir")) { 01261 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01262 } else { 01263 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01264 } 01265 } else if (!strcasecmp(var, "options")) { 01266 apply_options(vmu, value); 01267 } 01268 }
| static void apply_options | ( | struct ast_vm_user * | vmu, | |
| const char * | options | |||
| ) | [static] |
Destructively Parse options and apply.
Definition at line 1386 of file app_voicemail.c.
References apply_option(), ast_strdupa, strsep(), value, and var.
Referenced by append_mailbox(), apply_option(), and AST_TEST_DEFINE().
01387 { 01388 char *stringp; 01389 char *s; 01390 char *var, *value; 01391 stringp = ast_strdupa(options); 01392 while ((s = strsep(&stringp, "|"))) { 01393 value = s; 01394 if ((var = strsep(&value, "=")) && value) { 01395 apply_option(vmu, var, value); 01396 } 01397 } 01398 }
| 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 1405 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().
01406 { 01407 for (; var; var = var->next) { 01408 if (!strcasecmp(var->name, "vmsecret")) { 01409 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01410 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01411 if (ast_strlen_zero(retval->password)) { 01412 if (!ast_strlen_zero(var->value) && var->value[0] == '*') { 01413 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 01414 "\n\tmust be reset in voicemail.conf.\n", retval->mailbox); 01415 } else { 01416 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01417 } 01418 } 01419 } else if (!strcasecmp(var->name, "uniqueid")) { 01420 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01421 } else if (!strcasecmp(var->name, "pager")) { 01422 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01423 } else if (!strcasecmp(var->name, "email")) { 01424 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01425 } else if (!strcasecmp(var->name, "fullname")) { 01426 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01427 } else if (!strcasecmp(var->name, "context")) { 01428 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01429 } else if (!strcasecmp(var->name, "emailsubject")) { 01430 ast_free(retval->emailsubject); 01431 retval->emailsubject = ast_strdup(substitute_escapes(var->value)); 01432 } else if (!strcasecmp(var->name, "emailbody")) { 01433 ast_free(retval->emailbody); 01434 retval->emailbody = ast_strdup(substitute_escapes(var->value)); 01435 #ifdef IMAP_STORAGE 01436 } else if (!strcasecmp(var->name, "imapuser")) { 01437 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01438 retval->imapversion = imapversion; 01439 } else if (!strcasecmp(var->name, "imapserver")) { 01440 ast_copy_string(retval->imapserver, var->value, sizeof(retval->imapserver)); 01441 retval->imapversion = imapversion; 01442 } else if (!strcasecmp(var->name, "imapport")) { 01443 ast_copy_string(retval->imapport, var->value, sizeof(retval->imapport)); 01444 retval->imapversion = imapversion; 01445 } else if (!strcasecmp(var->name, "imapflags")) { 01446 ast_copy_string(retval->imapflags, var->value, sizeof(retval->imapflags)); 01447 retval->imapversion = imapversion; 01448 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01449 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01450 retval->imapversion = imapversion; 01451 } else if (!strcasecmp(var->name, "imapfolder")) { 01452 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01453 retval->imapversion = imapversion; 01454 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01455 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01456 retval->imapversion = imapversion; 01457 #endif 01458 } else 01459 apply_option(retval, var->name, var->value); 01460 } 01461 }
| AST_DATA_STRUCTURE | ( | vm_zone | , | |
| DATA_EXPORT_VM_ZONES | ||||
| ) |
| AST_DATA_STRUCTURE | ( | ast_vm_user | , | |
| DATA_EXPORT_VM_USERS | ||||
| ) |
| 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 4559 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.
04560 { 04561 struct ast_str *tmp = ast_str_alloca(80); 04562 int first_section = 1; 04563 04564 ast_str_reset(*end); 04565 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04566 for (; *start; start++) { 04567 int need_encoding = 0; 04568 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04569 need_encoding = 1; 04570 } 04571 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04572 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04573 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04574 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04575 /* Start new line */ 04576 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04577 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04578 first_section = 0; 04579 } 04580 if (need_encoding && *start == ' ') { 04581 ast_str_append(&tmp, -1, "_"); 04582 } else if (need_encoding) { 04583 ast_str_append(&tmp, -1, "=%hhX", *start); 04584 } else { 04585 ast_str_append(&tmp, -1, "%c", *start); 04586 } 04587 } 04588 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04589 return ast_str_buffer(*end); 04590 }
| 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 4487 of file app_voicemail.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
04488 { 04489 const char *ptr; 04490 04491 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04492 ast_str_set(buf, maxlen, "\""); 04493 for (ptr = from; *ptr; ptr++) { 04494 if (*ptr == '"' || *ptr == '\\') { 04495 ast_str_append(buf, maxlen, "\\%c", *ptr); 04496 } else { 04497 ast_str_append(buf, maxlen, "%c", *ptr); 04498 } 04499 } 04500 ast_str_append(buf, maxlen, "\""); 04501 04502 return ast_str_buffer(*buf); 04503 }
| AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10883 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.
10884 { 10885 int res = 0; 10886 struct ast_vm_user *vmu; 10887 /* language parameter seems to only be used for display in manager action */ 10888 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10889 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10890 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10891 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10892 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10893 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10894 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10895 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10896 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10897 #ifdef IMAP_STORAGE 10898 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10899 "imapfolder=INBOX|imapvmshareid=6000|imapserver=imapserver|imapport=1234|imapflags=flagged"; 10900 #endif 10901 10902 switch (cmd) { 10903 case TEST_INIT: 10904 info->name = "vmuser"; 10905 info->category = "/apps/app_voicemail/"; 10906 info->summary = "Vmuser unit test"; 10907 info->description = 10908 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10909 return AST_TEST_NOT_RUN; 10910 case TEST_EXECUTE: 10911 break; 10912 } 10913 10914 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10915 return AST_TEST_NOT_RUN; 10916 } 10917 ast_set_flag(vmu, VM_ALLOCED); 10918 populate_defaults(vmu); 10919 10920 apply_options(vmu, options_string); 10921 10922 if (!ast_test_flag(vmu, VM_ATTACH)) { 10923 ast_test_status_update(test, "Parse failure for attach option\n"); 10924 res = 1; 10925 } 10926 if (strcasecmp(vmu->attachfmt, "wav49")) { 10927 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10928 res = 1; 10929 } 10930 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10931 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10932 res = 1; 10933 } 10934 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10935 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10936 res = 1; 10937 } 10938 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10939 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10940 res = 1; 10941 } 10942 if (strcasecmp(vmu->zonetag, "central")) { 10943 ast_test_status_update(test, "Parse failure for tz option\n"); 10944 res = 1; 10945 } 10946 if (!ast_test_flag(vmu, VM_DELETE)) { 10947 ast_test_status_update(test, "Parse failure for delete option\n"); 10948 res = 1; 10949 } 10950 if (!ast_test_flag(vmu, VM_SAYCID)) { 10951 ast_test_status_update(test, "Parse failure for saycid option\n"); 10952 res = 1; 10953 } 10954 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10955 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10956 res = 1; 10957 } 10958 if (!ast_test_flag(vmu, VM_REVIEW)) { 10959 ast_test_status_update(test, "Parse failure for review option\n"); 10960 res = 1; 10961 } 10962 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10963 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10964 res = 1; 10965 } 10966 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10967 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10968 res = 1; 10969 } 10970 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10971 ast_test_status_update(test, "Parse failure for operator option\n"); 10972 res = 1; 10973 } 10974 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10975 ast_test_status_update(test, "Parse failure for envelope option\n"); 10976 res = 1; 10977 } 10978 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10979 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10980 res = 1; 10981 } 10982 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10983 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10984 res = 1; 10985 } 10986 if (vmu->saydurationm != 5) { 10987 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10988 res = 1; 10989 } 10990 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10991 ast_test_status_update(test, "Parse failure for forcename option\n"); 10992 res = 1; 10993 } 10994 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10995 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10996 res = 1; 10997 } 10998 if (strcasecmp(vmu->callback, "somecontext")) { 10999 ast_test_status_update(test, "Parse failure for callbacks option\n"); 11000 res = 1; 11001 } 11002 if (strcasecmp(vmu->dialout, "somecontext2")) { 11003 ast_test_status_update(test, "Parse failure for dialout option\n"); 11004 res = 1; 11005 } 11006 if (strcasecmp(vmu->exit, "somecontext3")) { 11007 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 11008 res = 1; 11009 } 11010 if (vmu->minsecs != 10) { 11011 ast_test_status_update(test, "Parse failure for minsecs option\n"); 11012 res = 1; 11013 } 11014 if (vmu->maxsecs != 100) { 11015 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 11016 res = 1; 11017 } 11018 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 11019 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 11020 res = 1; 11021 } 11022 if (vmu->maxdeletedmsg != 50) { 11023 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 11024 res = 1; 11025 } 11026 if (vmu->volgain != 1.3) { 11027 ast_test_status_update(test, "Parse failure for volgain option\n"); 11028 res = 1; 11029 } 11030 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 11031 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 11032 res = 1; 11033 } 11034 #ifdef IMAP_STORAGE 11035 apply_options(vmu, option_string2); 11036 11037 if (strcasecmp(vmu->imapuser, "imapuser")) { 11038 ast_test_status_update(test, "Parse failure for imapuser option\n"); 11039 res = 1; 11040 } 11041 if (strcasecmp(vmu->imappassword, "imappasswd")) { 11042 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 11043 res = 1; 11044 } 11045 if (strcasecmp(vmu->imapfolder, "INBOX")) { 11046 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 11047 res = 1; 11048 } 11049 if (strcasecmp(vmu->imapvmshareid, "6000")) { 11050 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 11051 res = 1; 11052 } 11053 if (strcasecmp(vmu->imapserver, "imapserver")) { 11054 ast_test_status_update(test, "Parse failure for imapserver option\n"); 11055 res = 1; 11056 } 11057 if (strcasecmp(vmu->imapport, "1234")) { 11058 ast_test_status_update(test, "Parse failure for imapport option\n"); 11059 res = 1; 11060 } 11061 if (strcasecmp(vmu->imapflags, "flagged")) { 11062 ast_test_status_update(test, "Parse failure for imapflags option\n"); 11063 res = 1; 11064 } 11065 #endif 11066 11067 free_user(vmu); 11068 return res ? AST_TEST_FAIL : AST_TEST_PASS; 11069 }
| 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. |
Definition at line 4365 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, BASEMAXINLINE, ENDL, errno, inchar(), baseio::iocp, and ochar().
04366 { 04367 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04368 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04369 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04370 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04371 int i, hiteof = 0; 04372 FILE *fi; 04373 struct baseio bio; 04374 04375 memset(&bio, 0, sizeof(bio)); 04376 bio.iocp = BASEMAXINLINE; 04377 04378 if (!(fi = fopen(filename, "rb"))) { 04379 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04380 return -1; 04381 } 04382 04383 while (!hiteof){ 04384 unsigned char igroup[3], ogroup[4]; 04385 int c, n; 04386 04387 memset(igroup, 0, sizeof(igroup)); 04388 04389 for (n = 0; n < 3; n++) { 04390 if ((c = inchar(&bio, fi)) == EOF) { 04391 hiteof = 1; 04392 break; 04393 } 04394 04395 igroup[n] = (unsigned char) c; 04396 } 04397 04398 if (n > 0) { 04399 ogroup[0]= dtable[igroup[0] >> 2]; 04400 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04401 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04402 ogroup[3]= dtable[igroup[2] & 0x3F]; 04403 04404 if (n < 3) { 04405 ogroup[3] = '='; 04406 04407 if (n < 2) 04408 ogroup[2] = '='; 04409 } 04410 04411 for (i = 0; i < 4; i++) 04412 ochar(&bio, ogroup[i], so); 04413 } 04414 } 04415 04416 fclose(fi); 04417 04418 if (fputs(ENDL, so) == EOF) { 04419 return 0; 04420 } 04421 04422 return 1; 04423 }
| 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. |
Definition at line 1364 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().
01365 { 01366 int res = -1; 01367 if (!strcmp(vmu->password, password)) { 01368 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01369 return 0; 01370 } 01371 01372 if (strlen(password) > 10) { 01373 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01374 } 01375 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01376 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime"); 01377 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01378 res = 0; 01379 } 01380 return res; 01381 }
| 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 4532 of file app_voicemail.c.
04533 { 04534 for (; *str; str++) { 04535 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 04536 return 1; 04537 } 04538 } 04539 return 0; 04540 }
| 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 1323 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_NOTICE, AST_LOG_WARNING, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and vm_check_password_shell().
Referenced by network_thread(), vm_newuser(), and vm_options().
01324 { 01325 /* check minimum length */ 01326 if (strlen(password) < minpassword) 01327 return 1; 01328 /* check that password does not contain '*' character */ 01329 if (!ast_strlen_zero(password) && password[0] == '*') 01330 return 1; 01331 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01332 char cmd[255], buf[255]; 01333 01334 ast_debug(1, "Verify password policies for %s\n", password); 01335 01336 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01337 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01338 ast_debug(5, "Result: %s\n", buf); 01339 if (!strncasecmp(buf, "VALID", 5)) { 01340 ast_debug(3, "Passed password check: '%s'\n", buf); 01341 return 0; 01342 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01343 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01344 return 0; 01345 } else { 01346 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01347 return 1; 01348 } 01349 } 01350 } 01351 return 0; 01352 }
| static int close_mailbox | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu | |||
| ) | [static] |
Definition at line 8044 of file app_voicemail.c.
References ast_check_realtime(), ast_debug, ast_free, ast_log(), AST_LOG_NOTICE, AST_LOG_WARNING, 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().
08045 { 08046 int x = 0; 08047 08048 #ifndef IMAP_STORAGE 08049 int last_msg_idx; 08050 int res = 0, nummsg; 08051 char fn2[PATH_MAX]; 08052 #endif 08053 08054 if (vms->lastmsg <= -1) { 08055 goto done; 08056 } 08057 08058 vms->curmsg = -1; 08059 #ifndef IMAP_STORAGE 08060 /* Get the deleted messages fixed */ 08061 if (vm_lock_path(vms->curdir)) { 08062 return ERROR_LOCK_PATH; 08063 } 08064 08065 /* update count as message may have arrived while we've got mailbox open */ 08066 last_msg_idx = last_message_index(vmu, vms->curdir); 08067 if (last_msg_idx != vms->lastmsg) { 08068 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 08069 } 08070 08071 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 08072 for (x = 0; x < last_msg_idx + 1; x++) { 08073 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 08074 /* Save this message. It's not in INBOX or hasn't been heard */ 08075 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08076 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 08077 break; 08078 } 08079 vms->curmsg++; 08080 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 08081 if (strcmp(vms->fn, fn2)) { 08082 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 08083 } 08084 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 08085 /* Move to old folder before deleting */ 08086 res = save_to_folder(vmu, vms, x, 1); 08087 if (res == ERROR_LOCK_PATH) { 08088 /* If save failed do not delete the message */ 08089 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 08090 vms->deleted[x] = 0; 08091 vms->heard[x] = 0; 08092 --x; 08093 } 08094 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 08095 /* Move to deleted folder */ 08096 res = save_to_folder(vmu, vms, x, 10); 08097 if (res == ERROR_LOCK_PATH) { 08098 /* If save failed do not delete the message */ 08099 vms->deleted[x] = 0; 08100 vms->heard[x] = 0; 08101 --x; 08102 } 08103 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 08104 /* If realtime storage enabled - we should explicitly delete this message, 08105 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08106 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08107 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08108 DELETE(vms->curdir, x, vms->fn, vmu); 08109 } 08110 } 08111 } 08112 08113 /* Delete ALL remaining messages */ 08114 nummsg = x - 1; 08115 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08116 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08117 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08118 DELETE(vms->curdir, x, vms->fn, vmu); 08119 } 08120 } 08121 ast_unlock_path(vms->curdir); 08122 #else /* defined(IMAP_STORAGE) */ 08123 if (vms->deleted) { 08124 /* Since we now expunge after each delete, deleting in reverse order 08125 * ensures that no reordering occurs between each step. */ 08126 for (x = vms->dh_arraysize - 1; x >= 0; x--) { 08127 if (vms->deleted[x]) { 08128 ast_debug(3, "IMAP delete of %d\n", x); 08129 DELETE(vms->curdir, x, vms->fn, vmu); 08130 } 08131 } 08132 } 08133 #endif 08134 08135 done: 08136 if (vms->deleted) { 08137 ast_free(vms->deleted); 08138 } 08139 if (vms->heard) { 08140 ast_free(vms->heard); 08141 } 08142 08143 return 0; 08144 }
| static char* complete_voicemail_show_users | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 11300 of file app_voicemail.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
11301 { 11302 int which = 0; 11303 int wordlen; 11304 struct ast_vm_user *vmu; 11305 const char *context = ""; 11306 11307 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11308 if (pos > 4) 11309 return NULL; 11310 if (pos == 3) 11311 return (state == 0) ? ast_strdup("for") : NULL; 11312 wordlen = strlen(word); 11313 AST_LIST_TRAVERSE(&users, vmu, list) { 11314 if (!strncasecmp(word, vmu->context, wordlen)) { 11315 if (context && strcmp(context, vmu->context) && ++which > state) 11316 return ast_strdup(vmu->context); 11317 /* ignore repeated contexts ? */ 11318 context = vmu->context; 11319 } 11320 } 11321 return NULL; 11322 }
| 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. |
Definition at line 4169 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(), filehelper(), iax2_register(), and vm_forwardoptions().
04170 { 04171 int ifd; 04172 int ofd; 04173 int res; 04174 int len; 04175 char buf[4096]; 04176 04177 #ifdef HARDLINK_WHEN_POSSIBLE 04178 /* Hard link if possible; saves disk space & is faster */ 04179 if (link(infile, outfile)) { 04180 #endif 04181 if ((ifd = open(infile, O_RDONLY)) < 0) { 04182 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04183 return -1; 04184 } 04185 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04186 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04187 close(ifd); 04188 return -1; 04189 } 04190 do { 04191 len = read(ifd, buf, sizeof(buf)); 04192 if (len < 0) { 04193 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04194 close(ifd); 04195 close(ofd); 04196 unlink(outfile); 04197 } 04198 if (len) { 04199 res = write(ofd, buf, len); 04200 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04201 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04202 close(ifd); 04203 close(ofd); 04204 unlink(outfile); 04205 } 04206 } 04207 } while (len); 04208 close(ifd); 04209 close(ofd); 04210 return 0; 04211 #ifdef HARDLINK_WHEN_POSSIBLE 04212 } else { 04213 /* Hard link succeeded */ 04214 return 0; 04215 } 04216 #endif 04217 }
| 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 5408 of file app_voicemail.c.
References ast_channel_language(), 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(), 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().
05409 { 05410 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05411 const char *frombox = mbox(vmu, imbox); 05412 const char *userfolder; 05413 int recipmsgnum; 05414 int res = 0; 05415 05416 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05417 05418 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05419 userfolder = "Urgent"; 05420 } else { 05421 userfolder = "INBOX"; 05422 } 05423 05424 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05425 05426 if (!dir) 05427 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05428 else 05429 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05430 05431 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05432 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05433 05434 if (vm_lock_path(todir)) 05435 return ERROR_LOCK_PATH; 05436 05437 recipmsgnum = last_message_index(recip, todir) + 1; 05438 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05439 make_file(topath, sizeof(topath), todir, recipmsgnum); 05440 #ifndef ODBC_STORAGE 05441 if (EXISTS(fromdir, msgnum, frompath, ast_channel_language(chan))) { 05442 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05443 } else { 05444 #endif 05445 /* If we are prepending a message for ODBC, then the message already 05446 * exists in the database, but we want to force copying from the 05447 * filesystem (since only the FS contains the prepend). */ 05448 copy_plain_file(frompath, topath); 05449 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05450 vm_delete(topath); 05451 #ifndef ODBC_STORAGE 05452 } 05453 #endif 05454 } else { 05455 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05456 res = -1; 05457 } 05458 ast_unlock_path(todir); 05459 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05460 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05461 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05462 flag); 05463 05464 return res; 05465 }
| static void copy_plain_file | ( | char * | frompath, | |
| char * | topath | |||
| ) | [static] |
Copies a voicemail information (envelope) file.
| frompath | ||
| topath |
Definition at line 4228 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().
04229 { 04230 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04231 struct ast_variable *tmp,*var = NULL; 04232 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04233 ast_filecopy(frompath, topath, NULL); 04234 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04235 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04236 if (ast_check_realtime("voicemail_data")) { 04237 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04238 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04239 for (tmp = var; tmp; tmp = tmp->next) { 04240 if (!strcasecmp(tmp->name, "origmailbox")) { 04241 origmailbox = tmp->value; 04242 } else if (!strcasecmp(tmp->name, "context")) { 04243 context = tmp->value; 04244 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04245 macrocontext = tmp->value; 04246 } else if (!strcasecmp(tmp->name, "exten")) { 04247 exten = tmp->value; 04248 } else if (!strcasecmp(tmp->name, "priority")) { 04249 priority = tmp->value; 04250 } else if (!strcasecmp(tmp->name, "callerchan")) { 04251 callerchan = tmp->value; 04252 } else if (!strcasecmp(tmp->name, "callerid")) { 04253 callerid = tmp->value; 04254 } else if (!strcasecmp(tmp->name, "origdate")) { 04255 origdate = tmp->value; 04256 } else if (!strcasecmp(tmp->name, "origtime")) { 04257 origtime = tmp->value; 04258 } else if (!strcasecmp(tmp->name, "category")) { 04259 category = tmp->value; 04260 } else if (!strcasecmp(tmp->name, "duration")) { 04261 duration = tmp->value; 04262 } 04263 } 04264 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); 04265 } 04266 copy(frompath2, topath2); 04267 ast_variables_destroy(var); 04268 }
| 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 4064 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().
04065 { 04066 04067 int vmcount = 0; 04068 DIR *vmdir = NULL; 04069 struct dirent *vment = NULL; 04070 04071 if (vm_lock_path(dir)) 04072 return ERROR_LOCK_PATH; 04073 04074 if ((vmdir = opendir(dir))) { 04075 while ((vment = readdir(vmdir))) { 04076 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 04077 vmcount++; 04078 } 04079 } 04080 closedir(vmdir); 04081 } 04082 ast_unlock_path(dir); 04083 04084 return vmcount; 04085 }
| 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 1780 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
01781 { 01782 mode_t mode = VOICEMAIL_DIR_MODE; 01783 int res; 01784 01785 make_dir(dest, len, context, ext, folder); 01786 if ((res = ast_mkdir(dest, mode))) { 01787 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01788 return -1; 01789 } 01790 return 0; 01791 }
| static int dialout | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| char * | num, | |||
| char * | outgoing_context | |||
| ) | [static] |
Definition at line 13399 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_waitfordigit(), ast_channel::context, ast_channel::exten, and ast_channel::priority.
Referenced by advanced_options(), and vm_execmain().
13400 { 13401 int cmd = 0; 13402 char destination[80] = ""; 13403 int retries = 0; 13404 13405 if (!num) { 13406 ast_verb(3, "Destination number will be entered manually\n"); 13407 while (retries < 3 && cmd != 't') { 13408 destination[1] = '\0'; 13409 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13410 if (!cmd) 13411 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13412 if (!cmd) 13413 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13414 if (!cmd) { 13415 cmd = ast_waitfordigit(chan, 6000); 13416 if (cmd) 13417 destination[0] = cmd; 13418 } 13419 if (!cmd) { 13420 retries++; 13421 } else { 13422 13423 if (cmd < 0) 13424 return 0; 13425 if (cmd == '*') { 13426 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13427 return 0; 13428 } 13429 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13430 retries++; 13431 else 13432 cmd = 't'; 13433 } 13434 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13435 } 13436 if (retries >= 3) { 13437 return 0; 13438 } 13439 13440 } else { 13441 ast_verb(3, "Destination number is CID number '%s'\n", num); 13442 ast_copy_string(destination, num, sizeof(destination)); 13443 } 13444 13445 if (!ast_strlen_zero(destination)) { 13446 if (destination[strlen(destination) -1 ] == '*') 13447 return 0; 13448 ast_verb(3, "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13449 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13450 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13451 chan->priority = 0; 13452 return 9; 13453 } 13454 return 0; 13455 }
| static struct ast_vm_user* find_or_create | ( | const char * | context, | |
| const char * | box | |||
| ) | [static, read] |
Definition at line 10786 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().
10787 { 10788 struct ast_vm_user *vmu; 10789 10790 if (!ast_strlen_zero(box) && box[0] == '*') { 10791 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10792 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10793 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10794 "\n\tand will be ignored.\n", box, context); 10795 return NULL; 10796 } 10797 10798 AST_LIST_TRAVERSE(&users, vmu, list) { 10799 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10800 if (strcasecmp(vmu->context, context)) { 10801 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10802 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10803 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10804 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10805 } 10806 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10807 return NULL; 10808 } 10809 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10810 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10811 return NULL; 10812 } 10813 } 10814 10815 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10816 return NULL; 10817 10818 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10819 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10820 10821 AST_LIST_INSERT_TAIL(&users, vmu, list); 10822 10823 return vmu; 10824 }
| 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 1532 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.
01533 { 01534 /* This function could be made to generate one from a database, too */ 01535 struct ast_vm_user *vmu = NULL, *cur; 01536 AST_LIST_LOCK(&users); 01537 01538 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01539 context = "default"; 01540 01541 AST_LIST_TRAVERSE(&users, cur, list) { 01542 #ifdef IMAP_STORAGE 01543 if (cur->imapversion != imapversion) { 01544 continue; 01545 } 01546 #endif 01547 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01548 break; 01549 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01550 break; 01551 } 01552 if (cur) { 01553 /* Make a copy, so that on a reload, we have no race */ 01554 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01555 *vmu = *cur; 01556 if (!ivm) { 01557 vmu->emailbody = ast_strdup(cur->emailbody); 01558 vmu->emailsubject = ast_strdup(cur->emailsubject); 01559 } 01560 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01561 AST_LIST_NEXT(vmu, list) = NULL; 01562 } 01563 } else 01564 vmu = find_user_realtime(ivm, context, mailbox); 01565 AST_LIST_UNLOCK(&users); 01566 return vmu; 01567 }
| 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 1495 of file app_voicemail.c.
References apply_options_full(), ast_calloc, ast_copy_string(), ast_free, ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), globalflags, ast_vm_user::mailbox, populate_defaults(), SENTINEL, var, VM_ALLOCED, and VM_SEARCH.
01496 { 01497 struct ast_variable *var; 01498 struct ast_vm_user *retval; 01499 01500 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01501 if (!ivm) 01502 ast_set_flag(retval, VM_ALLOCED); 01503 else 01504 memset(retval, 0, sizeof(*retval)); 01505 if (mailbox) 01506 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01507 populate_defaults(retval); 01508 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) 01509 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01510 else 01511 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01512 if (var) { 01513 apply_options_full(retval, var); 01514 ast_variables_destroy(var); 01515 } else { 01516 if (!ivm) 01517 ast_free(retval); 01518 retval = NULL; 01519 } 01520 } 01521 return retval; 01522 }
| 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 forward message mode (is_new_message == 0):
Definition at line 7236 of file app_voicemail.c.
References ast_channel_language(), 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(), STORE, ast_party_name::str, ast_party_number::str, strsep(), vm_state::username, ast_party_name::valid, ast_party_number::valid, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), and VM_FWDURGAUTO.
Referenced by vm_execmain().
07237 { 07238 #ifdef IMAP_STORAGE 07239 int todircount = 0; 07240 struct vm_state *dstvms; 07241 #endif 07242 char username[70]=""; 07243 char fn[PATH_MAX]; /* for playback of name greeting */ 07244 char ecodes[16] = "#"; 07245 int res = 0, cmd = 0; 07246 struct ast_vm_user *receiver = NULL, *vmtmp; 07247 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07248 char *stringp; 07249 const char *s; 07250 int saved_messages = 0; 07251 int valid_extensions = 0; 07252 char *dir; 07253 int curmsg; 07254 char urgent_str[7] = ""; 07255 int prompt_played = 0; 07256 #ifndef IMAP_STORAGE 07257 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07258 #endif 07259 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07260 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07261 } 07262 07263 if (vms == NULL) return -1; 07264 dir = vms->curdir; 07265 curmsg = vms->curmsg; 07266 07267 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07268 while (!res && !valid_extensions) { 07269 int use_directory = 0; 07270 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07271 int done = 0; 07272 int retries = 0; 07273 cmd = 0; 07274 while ((cmd >= 0) && !done ){ 07275 if (cmd) 07276 retries = 0; 07277 switch (cmd) { 07278 case '1': 07279 use_directory = 0; 07280 done = 1; 07281 break; 07282 case '2': 07283 use_directory = 1; 07284 done = 1; 07285 break; 07286 case '*': 07287 cmd = 't'; 07288 done = 1; 07289 break; 07290 default: 07291 /* Press 1 to enter an extension press 2 to use the directory */ 07292 cmd = ast_play_and_wait(chan, "vm-forward"); 07293 if (!cmd) { 07294 cmd = ast_waitfordigit(chan, 3000); 07295 } 07296 if (!cmd) { 07297 retries++; 07298 } 07299 if (retries > 3) { 07300 cmd = 't'; 07301 done = 1; 07302 } 07303 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07304 } 07305 } 07306 if (cmd < 0 || cmd == 't') 07307 break; 07308 } 07309 07310 if (use_directory) { 07311 /* use app_directory */ 07312 07313 char old_context[sizeof(chan->context)]; 07314 char old_exten[sizeof(chan->exten)]; 07315 int old_priority; 07316 struct ast_app* directory_app; 07317 07318 directory_app = pbx_findapp("Directory"); 07319 if (directory_app) { 07320 char vmcontext[256]; 07321 /* make backup copies */ 07322 memcpy(old_context, chan->context, sizeof(chan->context)); 07323 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07324 old_priority = chan->priority; 07325 07326 /* call the the Directory, changes the channel */ 07327 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07328 res = pbx_exec(chan, directory_app, vmcontext); 07329 07330 ast_copy_string(username, chan->exten, sizeof(username)); 07331 07332 /* restore the old context, exten, and priority */ 07333 memcpy(chan->context, old_context, sizeof(chan->context)); 07334 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07335 chan->priority = old_priority; 07336 } else { 07337 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07338 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07339 } 07340 } else { 07341 /* Ask for an extension */ 07342 ast_test_suite_event_notify("PLAYBACK", "Message: vm-extension"); 07343 res = ast_streamfile(chan, "vm-extension", ast_channel_language(chan)); /* "extension" */ 07344 prompt_played++; 07345 if (res || prompt_played > 4) 07346 break; 07347 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#")) < 0) 07348 break; 07349 } 07350 07351 /* start all over if no username */ 07352 if (ast_strlen_zero(username)) 07353 continue; 07354 stringp = username; 07355 s = strsep(&stringp, "*"); 07356 /* start optimistic */ 07357 valid_extensions = 1; 07358 while (s) { 07359 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07360 int oldmsgs; 07361 int newmsgs; 07362 int capacity; 07363 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07364 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07365 /* Shouldn't happen, but allow trying another extension if it does */ 07366 res = ast_play_and_wait(chan, "pbx-invalid"); 07367 valid_extensions = 0; 07368 break; 07369 } 07370 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07371 if ((newmsgs + oldmsgs) >= capacity) { 07372 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07373 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07374 valid_extensions = 0; 07375 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07376 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07377 free_user(vmtmp); 07378 } 07379 inprocess_count(receiver->mailbox, receiver->context, -1); 07380 break; 07381 } 07382 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07383 } else { 07384 /* XXX Optimization for the future. When we encounter a single bad extension, 07385 * bailing out on all of the extensions may not be the way to go. We should 07386 * probably just bail on that single extension, then allow the user to enter 07387 * several more. XXX 07388 */ 07389 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07390 free_user(receiver); 07391 } 07392 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07393 /* "I am sorry, that's not a valid extension. Please try again." */ 07394 res = ast_play_and_wait(chan, "pbx-invalid"); 07395 valid_extensions = 0; 07396 break; 07397 } 07398 07399 /* play name if available, else play extension number */ 07400 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07401 RETRIEVE(fn, -1, s, receiver->context); 07402 if (ast_fileexists(fn, NULL, NULL) > 0) { 07403 res = ast_stream_and_wait(chan, fn, ecodes); 07404 if (res) { 07405 DISPOSE(fn, -1); 07406 return res; 07407 } 07408 } else { 07409 res = ast_say_digit_str(chan, s, ecodes, ast_channel_language(chan)); 07410 } 07411 DISPOSE(fn, -1); 07412 07413 s = strsep(&stringp, "*"); 07414 } 07415 /* break from the loop of reading the extensions */ 07416 if (valid_extensions) 07417 break; 07418 } 07419 /* check if we're clear to proceed */ 07420 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07421 return res; 07422 if (is_new_message == 1) { 07423 struct leave_vm_options leave_options; 07424 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07425 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07426 07427 /* Send VoiceMail */ 07428 memset(&leave_options, 0, sizeof(leave_options)); 07429 leave_options.record_gain = record_gain; 07430 cmd = leave_voicemail(chan, mailbox, &leave_options); 07431 } else { 07432 /* Forward VoiceMail */ 07433 long duration = 0; 07434 struct vm_state vmstmp; 07435 int copy_msg_result = 0; 07436 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07437 07438 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07439 07440 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07441 if (!cmd) { 07442 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07443 #ifdef IMAP_STORAGE 07444 int attach_user_voicemail; 07445 char *myserveremail = serveremail; 07446 07447 /* get destination mailbox */ 07448 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07449 if (!dstvms) { 07450 dstvms = create_vm_state_from_user(vmtmp); 07451 } 07452 if (dstvms) { 07453 init_mailstream(dstvms, 0); 07454 if (!dstvms->mailstream) { 07455 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07456 } else { 07457 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07458 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07459 } 07460 } else { 07461 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07462 } 07463 if (!ast_strlen_zero(vmtmp->serveremail)) 07464 myserveremail = vmtmp->serveremail; 07465 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07466 /* NULL category for IMAP storage */ 07467 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07468 dstvms->curbox, 07469 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07470 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07471 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07472 NULL, urgent_str); 07473 #else 07474 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07475 #endif 07476 saved_messages++; 07477 AST_LIST_REMOVE_CURRENT(list); 07478 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07479 free_user(vmtmp); 07480 if (res) 07481 break; 07482 } 07483 AST_LIST_TRAVERSE_SAFE_END; 07484 if (saved_messages > 0 && !copy_msg_result) { 07485 /* give confirmation that the message was saved */ 07486 /* commented out since we can't forward batches yet 07487 if (saved_messages == 1) 07488 res = ast_play_and_wait(chan, "vm-message"); 07489 else 07490 res = ast_play_and_wait(chan, "vm-messages"); 07491 if (!res) 07492 res = ast_play_and_wait(chan, "vm-saved"); */ 07493 #ifdef IMAP_STORAGE 07494 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07495 if (ast_strlen_zero(vmstmp.introfn)) 07496 #endif 07497 res = ast_play_and_wait(chan, "vm-msgsaved"); 07498 } 07499 #ifndef IMAP_STORAGE 07500 else { 07501 /* with IMAP, mailbox full warning played by imap_check_limits */ 07502 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07503 } 07504 /* Restore original message without prepended message if backup exists */ 07505 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07506 strcpy(textfile, msgfile); 07507 strcpy(backup, msgfile); 07508 strcpy(backup_textfile, msgfile); 07509 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07510 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07511 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07512 if (ast_fileexists(backup, NULL, NULL) > 0) { 07513 ast_filerename(backup, msgfile, NULL); 07514 rename(backup_textfile, textfile); 07515 } 07516 #endif 07517 } 07518 DISPOSE(dir, curmsg); 07519 #ifndef IMAP_STORAGE 07520 if (cmd) { /* assuming hangup, cleanup backup file */ 07521 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07522 strcpy(textfile, msgfile); 07523 strcpy(backup_textfile, msgfile); 07524 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07525 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07526 rename(backup_textfile, textfile); 07527 } 07528 #endif 07529 } 07530 07531 /* If anything failed above, we still have this list to free */ 07532 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07533 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07534 free_user(vmtmp); 07535 } 07536 return res ? res : cmd; 07537 }
| static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1835 of file app_voicemail.c.
References ast_free, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, and VM_ALLOCED.
01836 { 01837 if (ast_test_flag(vmu, VM_ALLOCED)) { 01838 01839 ast_free(vmu->emailbody); 01840 vmu->emailbody = NULL; 01841 01842 ast_free(vmu->emailsubject); 01843 vmu->emailsubject = NULL; 01844 01845 ast_free(vmu); 01846 } 01847 }
| static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11906 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().
11907 { 11908 struct ast_vm_user *current; 11909 AST_LIST_LOCK(&users); 11910 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11911 ast_set_flag(current, VM_ALLOCED); 11912 free_user(current); 11913 } 11914 AST_LIST_UNLOCK(&users); 11915 }
| static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11918 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().
11919 { 11920 struct vm_zone *zcur; 11921 AST_LIST_LOCK(&zones); 11922 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11923 free_zone(zcur); 11924 AST_LIST_UNLOCK(&zones); 11925 }
| static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5172 of file app_voicemail.c.
References ast_free.
05173 { 05174 ast_free(z); 05175 }
| 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. |
Definition at line 5128 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
05129 { 05130 struct ast_tm tm; 05131 struct timeval t = ast_tvnow(); 05132 05133 ast_localtime(&t, &tm, "UTC"); 05134 05135 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05136 }
| 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 6848 of file app_voicemail.c.
References ast_channel_language(), 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().
06849 { 06850 int x; 06851 int d; 06852 char fn[PATH_MAX]; 06853 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06854 if (d) 06855 return d; 06856 for (x = start; x < 5; x++) { /* For all folders */ 06857 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, ast_channel_language(chan), NULL))) 06858 return d; 06859 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06860 if (d) 06861 return d; 06862 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06863 06864 /* The inbox folder can have its name changed under certain conditions 06865 * so this checks if the sound file exists for the inbox folder name and 06866 * if it doesn't, plays the default name instead. */ 06867 if (x == 0) { 06868 if (ast_fileexists(fn, NULL, NULL)) { 06869 d = vm_play_folder_name(chan, fn); 06870 } else { 06871 ast_verb(1, "failed to find %s\n", fn); 06872 d = vm_play_folder_name(chan, "vm-INBOX"); 06873 } 06874 } else { 06875 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06876 d = vm_play_folder_name(chan, fn); 06877 } 06878 06879 if (d) 06880 return d; 06881 d = ast_waitfordigit(chan, 500); 06882 if (d) 06883 return d; 06884 } 06885 06886 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06887 if (d) 06888 return d; 06889 d = ast_waitfordigit(chan, 4000); 06890 return d; 06891 }
| 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. |
Definition at line 6905 of file app_voicemail.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
Referenced by vm_execmain().
06906 { 06907 int res = 0; 06908 int loops = 0; 06909 06910 res = ast_play_and_wait(chan, fn); /* Folder name */ 06911 while (((res < '0') || (res > '9')) && 06912 (res != '#') && (res >= 0) && 06913 loops < 4) { 06914 res = get_folder(chan, 0); 06915 loops++; 06916 } 06917 if (loops == 4) { /* give up */ 06918 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06919 return '#'; 06920 } 06921 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06922 return res; 06923 }
| static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1822 of file app_voicemail.c.
References ARRAY_LEN, and mailbox_folders.
Referenced by vm_execmain().
01823 { 01824 size_t i; 01825 01826 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01827 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01828 return i; 01829 } 01830 } 01831 01832 return -1; 01833 }
| static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11682 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::mailbox, mwi_sub_task::mailbox, poll_subscribed_mailbox(), mwi_sub_task::uniqueid, and mwi_sub::uniqueid.
Referenced by mwi_sub_event_cb().
11683 { 11684 unsigned int len; 11685 struct mwi_sub *mwi_sub; 11686 struct mwi_sub_task *p = datap; 11687 11688 len = sizeof(*mwi_sub); 11689 if (!ast_strlen_zero(p->mailbox)) 11690 len += strlen(p->mailbox); 11691 11692 if (!ast_strlen_zero(p->context)) 11693 len += strlen(p->context) + 1; /* Allow for seperator */ 11694 11695 if (!(mwi_sub = ast_calloc(1, len))) 11696 return -1; 11697 11698 mwi_sub->uniqueid = p->uniqueid; 11699 if (!ast_strlen_zero(p->mailbox)) 11700 strcpy(mwi_sub->mailbox, p->mailbox); 11701 11702 if (!ast_strlen_zero(p->context)) { 11703 strcat(mwi_sub->mailbox, "@"); 11704 strcat(mwi_sub->mailbox, p->context); 11705 } 11706 11707 AST_RWLIST_WRLOCK(&mwi_subs); 11708 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11709 AST_RWLIST_UNLOCK(&mwi_subs); 11710 ast_free((void *) p->mailbox); 11711 ast_free((void *) p->context); 11712 ast_free(p); 11713 poll_subscribed_mailbox(mwi_sub); 11714 return 0; 11715 }
| static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11660 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, mwi_sub::entry, mwi_sub_destroy(), and mwi_sub::uniqueid.
Referenced by mwi_unsub_event_cb().
11661 { 11662 struct mwi_sub *mwi_sub; 11663 uint32_t *uniqueid = datap; 11664 11665 AST_RWLIST_WRLOCK(&mwi_subs); 11666 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11667 if (mwi_sub->uniqueid == *uniqueid) { 11668 AST_LIST_REMOVE_CURRENT(entry); 11669 break; 11670 } 11671 } 11672 AST_RWLIST_TRAVERSE_SAFE_END 11673 AST_RWLIST_UNLOCK(&mwi_subs); 11674 11675 if (mwi_sub) 11676 mwi_sub_destroy(mwi_sub); 11677 11678 ast_free(uniqueid); 11679 return 0; 11680 }
| 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 11435 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.
11436 { 11437 switch (cmd) { 11438 case CLI_INIT: 11439 e->command = "voicemail reload"; 11440 e->usage = 11441 "Usage: voicemail reload\n" 11442 " Reload voicemail configuration\n"; 11443 return NULL; 11444 case CLI_GENERATE: 11445 return NULL; 11446 } 11447 11448 if (a->argc != 2) 11449 return CLI_SHOWUSAGE; 11450 11451 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11452 load_config(1); 11453 11454 return CLI_SUCCESS; 11455 }
| 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 11325 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.
11326 { 11327 struct ast_vm_user *vmu; 11328 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11329 const char *context = NULL; 11330 int users_counter = 0; 11331 11332 switch (cmd) { 11333 case CLI_INIT: 11334 e->command = "voicemail show users"; 11335 e->usage = 11336 "Usage: voicemail show users [for <context>]\n" 11337 " Lists all mailboxes currently set up\n"; 11338 return NULL; 11339 case CLI_GENERATE: 11340 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11341 } 11342 11343 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11344 return CLI_SHOWUSAGE; 11345 if (a->argc == 5) { 11346 if (strcmp(a->argv[3],"for")) 11347 return CLI_SHOWUSAGE; 11348 context = a->argv[4]; 11349 } 11350 11351 if (ast_check_realtime("voicemail")) { 11352 if (!context) { 11353 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11354 return CLI_SHOWUSAGE; 11355 } 11356 return show_users_realtime(a->fd, context); 11357 } 11358 11359 AST_LIST_LOCK(&users); 11360 if (AST_LIST_EMPTY(&users)) { 11361 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11362 AST_LIST_UNLOCK(&users); 11363 return CLI_FAILURE; 11364 } 11365 if (a->argc == 3) 11366 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11367 else { 11368 int count = 0; 11369 AST_LIST_TRAVERSE(&users, vmu, list) { 11370 if (!strcmp(context, vmu->context)) 11371 count++; 11372 } 11373 if (count) { 11374 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11375 } else { 11376 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11377 AST_LIST_UNLOCK(&users); 11378 return CLI_FAILURE; 11379 } 11380 } 11381 AST_LIST_TRAVERSE(&users, vmu, list) { 11382 int newmsgs = 0, oldmsgs = 0; 11383 char count[12], tmp[256] = ""; 11384 11385 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 11386 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11387 inboxcount(tmp, &newmsgs, &oldmsgs); 11388 snprintf(count, sizeof(count), "%d", newmsgs); 11389 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11390 users_counter++; 11391 } 11392 } 11393 AST_LIST_UNLOCK(&users); 11394 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11395 return CLI_SUCCESS; 11396 }
| 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 11399 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, vm_zone::msg_format, vm_zone::name, vm_zone::timezone, and ast_cli_entry::usage.
11400 { 11401 struct vm_zone *zone; 11402 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11403 char *res = CLI_SUCCESS; 11404 11405 switch (cmd) { 11406 case CLI_INIT: 11407 e->command = "voicemail show zones"; 11408 e->usage = 11409 "Usage: voicemail show zones\n" 11410 " Lists zone message formats\n"; 11411 return NULL; 11412 case CLI_GENERATE: 11413 return NULL; 11414 } 11415 11416 if (a->argc != 3) 11417 return CLI_SHOWUSAGE; 11418 11419 AST_LIST_LOCK(&zones); 11420 if (!AST_LIST_EMPTY(&zones)) { 11421 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11422 AST_LIST_TRAVERSE(&zones, zone, list) { 11423 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11424 } 11425 } else { 11426 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11427 res = CLI_FAILURE; 11428 } 11429 AST_LIST_UNLOCK(&zones); 11430 11431 return res; 11432 }
| 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 |
Definition at line 5520 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
Referenced by dahdi_handle_event(), do_monitor(), handle_hd_hf(), handle_init_event(), handle_request(), load_module(), mgcp_hangup(), mgcp_request(), mwi_send_init(), my_has_voicemail(), and vm_execmain().
05521 { 05522 char tmp[256], *tmp2 = tmp, *box, *context; 05523 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05524 if (ast_strlen_zero(folder)) { 05525 folder = "INBOX"; 05526 } 05527 while ((box = strsep(&tmp2, ",&"))) { 05528 if ((context = strchr(box, '@'))) 05529 *context++ = '\0'; 05530 else 05531 context = "default"; 05532 if (__has_voicemail(context, box, folder, 1)) 05533 return 1; 05534 /* If we are checking INBOX, we should check Urgent as well */ 05535 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05536 return 1; 05537 } 05538 } 05539 return 0; 05540 }
| static int inboxcount | ( | const char * | mailbox, | |
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) | [static] |
Definition at line 5602 of file app_voicemail.c.
References inboxcount2().
Referenced by forward_message(), handle_voicemail_show_users(), leave_voicemail(), load_module(), and manager_list_voicemail_users().
05603 { 05604 int urgentmsgs = 0; 05605 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05606 if (newmsgs) { 05607 *newmsgs += urgentmsgs; 05608 } 05609 return res; 05610 }
| static int inboxcount2 | ( | const char * | mailbox, | |
| int * | urgentmsgs, | |||
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) | [static] |
Definition at line 5543 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
Referenced by append_mailbox(), inboxcount(), load_module(), poll_subscribed_mailbox(), run_externnotify(), and vm_users_data_provider_get_helper().
05544 { 05545 char tmp[256]; 05546 char *context; 05547 05548 /* If no mailbox, return immediately */ 05549 if (ast_strlen_zero(mailbox)) 05550 return 0; 05551 05552 if (newmsgs) 05553 *newmsgs = 0; 05554 if (oldmsgs) 05555 *oldmsgs = 0; 05556 if (urgentmsgs) 05557 *urgentmsgs = 0; 05558 05559 if (strchr(mailbox, ',')) { 05560 int tmpnew, tmpold, tmpurgent; 05561 char *mb, *cur; 05562 05563 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05564 mb = tmp; 05565 while ((cur = strsep(&mb, ", "))) { 05566 if (!ast_strlen_zero(cur)) { 05567 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05568 return -1; 05569 else { 05570 if (newmsgs) 05571 *newmsgs += tmpnew; 05572 if (oldmsgs) 05573 *oldmsgs += tmpold; 05574 if (urgentmsgs) 05575 *urgentmsgs += tmpurgent; 05576 } 05577 } 05578 } 05579 return 0; 05580 } 05581 05582 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05583 05584 if ((context = strchr(tmp, '@'))) 05585 *context++ = '\0'; 05586 else 05587 context = "default"; 05588 05589 if (newmsgs) 05590 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05591 if (oldmsgs) 05592 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05593 if (urgentmsgs) 05594 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05595 05596 return 0; 05597 }
| static int inbuf | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4300 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(), sip_addheader(), and sip_removeheader().
04301 { 04302 int l; 04303 04304 if (bio->ateof) 04305 return 0; 04306 04307 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04308 if (ferror(fi)) 04309 return -1; 04310 04311 bio->ateof = 1; 04312 return 0; 04313 } 04314 04315 bio->iolen = l; 04316 bio->iocp = 0; 04317 04318 return 1; 04319 }
| static int inchar | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
utility used by base_encode()
Definition at line 4324 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
04325 { 04326 if (bio->iocp>=bio->iolen) { 04327 if (!inbuf(bio, fi)) 04328 return EOF; 04329 } 04330 04331 return bio->iobuf[bio->iocp++]; 04332 }
| static int inprocess_cmp_fn | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1009 of file app_voicemail.c.
References CMP_MATCH, inprocess::context, and inprocess::mailbox.
Referenced by load_module().
01010 { 01011 struct inprocess *i = obj, *j = arg; 01012 if (strcmp(i->mailbox, j->mailbox)) { 01013 return 0; 01014 } 01015 return !strcmp(i->context, j->context) ? CMP_MATCH : 0; 01016 }
| static int inprocess_count | ( | const char * | context, | |
| const char * | mailbox, | |||
| int | delta | |||
| ) | [static] |
Definition at line 1018 of file app_voicemail.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, 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().
01019 { 01020 struct inprocess *i, *arg = alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 01021 arg->context = arg->mailbox + strlen(mailbox) + 1; 01022 strcpy(arg->mailbox, mailbox); /* SAFE */ 01023 strcpy(arg->context, context); /* SAFE */ 01024 ao2_lock(inprocess_container); 01025 if ((i = ao2_find(inprocess_container, arg, 0))) { 01026 int ret = ast_atomic_fetchadd_int(&i->count, delta); 01027 ao2_unlock(inprocess_container); 01028 ao2_ref(i, -1); 01029 return ret; 01030 } 01031 if (delta < 0) { 01032 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 01033 } 01034 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 01035 ao2_unlock(inprocess_container); 01036 return 0; 01037 } 01038 i->context = i->mailbox + strlen(mailbox) + 1; 01039 strcpy(i->mailbox, mailbox); /* SAFE */ 01040 strcpy(i->context, context); /* SAFE */ 01041 i->count = delta; 01042 ao2_link(inprocess_container, i); 01043 ao2_unlock(inprocess_container); 01044 ao2_ref(i, -1); 01045 return 0; 01046 }
| static int inprocess_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1003 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 5138 of file app_voicemail.c.
References ast_channel_language(), ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, and RETRIEVE.
05139 { 05140 int res; 05141 char fn[PATH_MAX]; 05142 char dest[PATH_MAX]; 05143 05144 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05145 05146 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05147 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05148 return -1; 05149 } 05150 05151 RETRIEVE(fn, -1, ext, context); 05152 if (ast_fileexists(fn, NULL, NULL) > 0) { 05153 res = ast_stream_and_wait(chan, fn, ecodes); 05154 if (res) { 05155 DISPOSE(fn, -1); 05156 return res; 05157 } 05158 } else { 05159 /* Dispose just in case */ 05160 DISPOSE(fn, -1); 05161 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05162 if (res) 05163 return res; 05164 res = ast_say_digit_str(chan, ext, ecodes, ast_channel_language(chan)); 05165 if (res) 05166 return res; 05167 } 05168 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05169 return res; 05170 }
| 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. |
Definition at line 1470 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by actual_load_config().
01471 { 01472 int i; 01473 char *local_key = ast_strdupa(key); 01474 01475 for (i = 0; i < strlen(key); ++i) { 01476 if (!strchr(VALID_DTMF, *local_key)) { 01477 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01478 return 0; 01479 } 01480 local_key++; 01481 } 01482 return 1; 01483 }
| 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. |
Definition at line 4118 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().
04119 { 04120 int x; 04121 unsigned char map[MAXMSGLIMIT] = ""; 04122 DIR *msgdir; 04123 struct dirent *msgdirent; 04124 int msgdirint; 04125 char extension[4]; 04126 int stopcount = 0; 04127 04128 /* Reading the entire directory into a file map scales better than 04129 * doing a stat repeatedly on a predicted sequence. I suspect this 04130 * is partially due to stat(2) internally doing a readdir(2) itself to 04131 * find each file. */ 04132 if (!(msgdir = opendir(dir))) { 04133 return -1; 04134 } 04135 04136 while ((msgdirent = readdir(msgdir))) { 04137 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04138 map[msgdirint] = 1; 04139 stopcount++; 04140 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04141 } 04142 } 04143 closedir(msgdir); 04144 04145 for (x = 0; x < vmu->maxmsg; x++) { 04146 if (map[x] == 1) { 04147 stopcount--; 04148 } else if (map[x] == 0 && !stopcount) { 04149 break; 04150 } 04151 } 04152 04153 return x - 1; 04154 }
| 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 5675 of file app_voicemail.c.
References ast_callerid_merge(), ast_canmatch_extension(), ast_channel_language(), ast_channel_lock, ast_channel_name(), 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_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, 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, 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, strsep(), transfer, ast_party_name::valid, ast_party_number::valid, vm_lock_path(), VM_OPERATOR, VOICEMAIL_DIR_MODE, and VOICEMAIL_FILE_MODE.
05676 { 05677 #ifdef IMAP_STORAGE 05678 int newmsgs, oldmsgs; 05679 #else 05680 char urgdir[PATH_MAX]; 05681 #endif 05682 char txtfile[PATH_MAX]; 05683 char tmptxtfile[PATH_MAX]; 05684 struct vm_state *vms = NULL; 05685 char callerid[256]; 05686 FILE *txt; 05687 char date[256]; 05688 int txtdes; 05689 int res = 0; 05690 int msgnum; 05691 int duration = 0; 05692 int sound_duration = 0; 05693 int ausemacro = 0; 05694 int ousemacro = 0; 05695 int ouseexten = 0; 05696 char tmpdur[16]; 05697 char priority[16]; 05698 char origtime[16]; 05699 char dir[PATH_MAX]; 05700 char tmpdir[PATH_MAX]; 05701 char fn[PATH_MAX]; 05702 char prefile[PATH_MAX] = ""; 05703 char tempfile[PATH_MAX] = ""; 05704 char ext_context[256] = ""; 05705 char fmt[80]; 05706 char *context; 05707 char ecodes[17] = "#"; 05708 struct ast_str *tmp = ast_str_create(16); 05709 char *tmpptr; 05710 struct ast_vm_user *vmu; 05711 struct ast_vm_user svm; 05712 const char *category = NULL; 05713 const char *code; 05714 const char *alldtmf = "0123456789ABCD*#"; 05715 char flag[80]; 05716 05717 if (!tmp) { 05718 return -1; 05719 } 05720 05721 ast_str_set(&tmp, 0, "%s", ext); 05722 ext = ast_str_buffer(tmp); 05723 if ((context = strchr(ext, '@'))) { 05724 *context++ = '\0'; 05725 tmpptr = strchr(context, '&'); 05726 } else { 05727 tmpptr = strchr(ext, '&'); 05728 } 05729 05730 if (tmpptr) 05731 *tmpptr++ = '\0'; 05732 05733 ast_channel_lock(chan); 05734 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05735 category = ast_strdupa(category); 05736 } 05737 ast_channel_unlock(chan); 05738 05739 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05740 ast_copy_string(flag, "Urgent", sizeof(flag)); 05741 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05742 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05743 } else { 05744 flag[0] = '\0'; 05745 } 05746 05747 ast_debug(3, "Before find_user\n"); 05748 if (!(vmu = find_user(&svm, context, ext))) { 05749 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05750 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05751 ast_free(tmp); 05752 return res; 05753 } 05754 /* Setup pre-file if appropriate */ 05755 if (strcmp(vmu->context, "default")) 05756 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05757 else 05758 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05759 05760 /* Set the path to the prefile. Will be one of 05761 VM_SPOOL_DIRcontext/ext/busy 05762 VM_SPOOL_DIRcontext/ext/unavail 05763 Depending on the flag set in options. 05764 */ 05765 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05766 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05767 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05768 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05769 } 05770 /* Set the path to the tmpfile as 05771 VM_SPOOL_DIR/context/ext/temp 05772 and attempt to create the folder structure. 05773 */ 05774 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05775 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05776 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05777 ast_free(tmp); 05778 return -1; 05779 } 05780 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05781 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05782 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05783 05784 DISPOSE(tempfile, -1); 05785 /* It's easier just to try to make it than to check for its existence */ 05786 #ifndef IMAP_STORAGE 05787 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05788 #else 05789 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05790 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05791 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05792 } 05793 #endif 05794 05795 /* Check current or macro-calling context for special extensions */ 05796 if (ast_test_flag(vmu, VM_OPERATOR)) { 05797 if (!ast_strlen_zero(vmu->exit)) { 05798 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05799 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05800 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05801 ouseexten = 1; 05802 } 05803 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05804 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05805 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05806 ouseexten = 1; 05807 } else if (!ast_strlen_zero(chan->macrocontext) 05808 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05809 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05810 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05811 ousemacro = 1; 05812 } 05813 } 05814 05815 if (!ast_strlen_zero(vmu->exit)) { 05816 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05817 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05818 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05819 } 05820 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05821 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05822 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05823 } else if (!ast_strlen_zero(chan->macrocontext) 05824 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05825 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05826 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05827 ausemacro = 1; 05828 } 05829 05830 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05831 for (code = alldtmf; *code; code++) { 05832 char e[2] = ""; 05833 e[0] = *code; 05834 if (strchr(ecodes, e[0]) == NULL 05835 && ast_canmatch_extension(chan, chan->context, e, 1, 05836 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05837 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05838 } 05839 } 05840 } 05841 05842 /* Play the beginning intro if desired */ 05843 if (!ast_strlen_zero(prefile)) { 05844 #ifdef ODBC_STORAGE 05845 int success = 05846 #endif 05847 RETRIEVE(prefile, -1, ext, context); 05848 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05849 if (ast_streamfile(chan, prefile, ast_channel_language(chan)) > -1) 05850 res = ast_waitstream(chan, ecodes); 05851 #ifdef ODBC_STORAGE 05852 if (success == -1) { 05853 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05854 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05855 store_file(prefile, vmu->mailbox, vmu->context, -1); 05856 } 05857 #endif 05858 } else { 05859 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05860 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05861 } 05862 DISPOSE(prefile, -1); 05863 if (res < 0) { 05864 ast_debug(1, "Hang up during prefile playback\n"); 05865 free_user(vmu); 05866 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05867 ast_free(tmp); 05868 return -1; 05869 } 05870 } 05871 if (res == '#') { 05872 /* On a '#' we skip the instructions */ 05873 ast_set_flag(options, OPT_SILENT); 05874 res = 0; 05875 } 05876 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05877 if (vmu->maxmsg == 0) { 05878 ast_debug(3, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05879 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05880 goto leave_vm_out; 05881 } 05882 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05883 res = ast_stream_and_wait(chan, INTRO, ecodes); 05884 if (res == '#') { 05885 ast_set_flag(options, OPT_SILENT); 05886 res = 0; 05887 } 05888 } 05889 if (res > 0) 05890 ast_stopstream(chan); 05891 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05892 other than the operator -- an automated attendant or mailbox login for example */ 05893 if (res == '*') { 05894 chan->exten[0] = 'a'; 05895 chan->exten[1] = '\0'; 05896 if (!ast_strlen_zero(vmu->exit)) { 05897 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05898 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05899 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05900 } 05901 chan->priority = 0; 05902 free_user(vmu); 05903 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05904 ast_free(tmp); 05905 return 0; 05906 } 05907 05908 /* Check for a '0' here */ 05909 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05910 transfer: 05911 if (ouseexten || ousemacro) { 05912 chan->exten[0] = 'o'; 05913 chan->exten[1] = '\0'; 05914 if (!ast_strlen_zero(vmu->exit)) { 05915 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05916 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05917 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05918 } 05919 ast_play_and_wait(chan, "transfer"); 05920 chan->priority = 0; 05921 free_user(vmu); 05922 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05923 } 05924 ast_free(tmp); 05925 return OPERATOR_EXIT; 05926 } 05927 05928 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05929 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05930 if (!ast_strlen_zero(options->exitcontext)) 05931 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05932 free_user(vmu); 05933 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05934 ast_free(tmp); 05935 return res; 05936 } 05937 05938 if (res < 0) { 05939 free_user(vmu); 05940 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05941 ast_free(tmp); 05942 return -1; 05943 } 05944 /* The meat of recording the message... All the announcements and beeps have been played*/ 05945 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05946 if (!ast_strlen_zero(fmt)) { 05947 msgnum = 0; 05948 05949 #ifdef IMAP_STORAGE 05950 /* Is ext a mailbox? */ 05951 /* must open stream for this user to get info! */ 05952 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05953 if (res < 0) { 05954 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05955 ast_free(tmp); 05956 return -1; 05957 } 05958 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05959 /* It is possible under certain circumstances that inboxcount did not 05960 * create a vm_state when it was needed. This is a catchall which will 05961 * rarely be used. 05962 */ 05963 if (!(vms = create_vm_state_from_user(vmu))) { 05964 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05965 ast_free(tmp); 05966 return -1; 05967 } 05968 } 05969 vms->newmessages++; 05970 05971 /* here is a big difference! We add one to it later */ 05972 msgnum = newmsgs + oldmsgs; 05973 ast_debug(3, "Messagecount set to %d\n", msgnum); 05974 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05975 /* set variable for compatibility */ 05976 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05977 05978 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05979 goto leave_vm_out; 05980 } 05981 #else 05982 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05983 res = ast_streamfile(chan, "vm-mailboxfull", ast_channel_language(chan)); 05984 if (!res) 05985 res = ast_waitstream(chan, ""); 05986 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05987 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05988 inprocess_count(vmu->mailbox, vmu->context, -1); 05989 goto leave_vm_out; 05990 } 05991 05992 #endif 05993 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05994 txtdes = mkstemp(tmptxtfile); 05995 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05996 if (txtdes < 0) { 05997 res = ast_streamfile(chan, "vm-mailboxfull", ast_channel_language(chan)); 05998 if (!res) 05999 res = ast_waitstream(chan, ""); 06000 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 06001 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06002 inprocess_count(vmu->mailbox, vmu->context, -1); 06003 goto leave_vm_out; 06004 } 06005 06006 /* Now play the beep once we have the message number for our next message. */ 06007 if (res >= 0) { 06008 /* Unless we're *really* silent, try to send the beep */ 06009 res = ast_stream_and_wait(chan, "beep", ""); 06010 } 06011 06012 /* Store information in real-time storage */ 06013 if (ast_check_realtime("voicemail_data")) { 06014 snprintf(priority, sizeof(priority), "%d", chan->priority); 06015 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 06016 get_date(date, sizeof(date)); 06017 ast_callerid_merge(callerid, sizeof(callerid), 06018 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06019 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06020 "Unknown"); 06021 ast_store_realtime("voicemail_data", 06022 "origmailbox", ext, 06023 "context", chan->context, 06024 "macrocontext", chan->macrocontext, 06025 "exten", chan->exten, 06026 "priority", priority, 06027 "callerchan", ast_channel_name(chan), 06028 "callerid", callerid, 06029 "origdate", date, 06030 "origtime", origtime, 06031 "category", S_OR(category, ""), 06032 "filename", tmptxtfile, 06033 SENTINEL); 06034 } 06035 06036 /* Store information */ 06037 txt = fdopen(txtdes, "w+"); 06038 if (txt) { 06039 get_date(date, sizeof(date)); 06040 ast_callerid_merge(callerid, sizeof(callerid), 06041 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06042 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06043 "Unknown"); 06044 fprintf(txt, 06045 ";\n" 06046 "; Message Information file\n" 06047 ";\n" 06048 "[message]\n" 06049 "origmailbox=%s\n" 06050 "context=%s\n" 06051 "macrocontext=%s\n" 06052 "exten=%s\n" 06053 "rdnis=%s\n" 06054 "priority=%d\n" 06055 "callerchan=%s\n" 06056 "callerid=%s\n" 06057 "origdate=%s\n" 06058 "origtime=%ld\n" 06059 "category=%s\n", 06060 ext, 06061 chan->context, 06062 chan->macrocontext, 06063 chan->exten, 06064 S_COR(chan->redirecting.from.number.valid, 06065 chan->redirecting.from.number.str, "unknown"), 06066 chan->priority, 06067 ast_channel_name(chan), 06068 callerid, 06069 date, (long) time(NULL), 06070 category ? category : ""); 06071 } else { 06072 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 06073 inprocess_count(vmu->mailbox, vmu->context, -1); 06074 if (ast_check_realtime("voicemail_data")) { 06075 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06076 } 06077 res = ast_streamfile(chan, "vm-mailboxfull", ast_channel_language(chan)); 06078 goto leave_vm_out; 06079 } 06080 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 06081 06082 if (txt) { 06083 fprintf(txt, "flag=%s\n", flag); 06084 if (sound_duration < vmu->minsecs) { 06085 fclose(txt); 06086 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 06087 ast_filedelete(tmptxtfile, NULL); 06088 unlink(tmptxtfile); 06089 if (ast_check_realtime("voicemail_data")) { 06090 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06091 } 06092 inprocess_count(vmu->mailbox, vmu->context, -1); 06093 } else { 06094 fprintf(txt, "duration=%d\n", duration); 06095 fclose(txt); 06096 if (vm_lock_path(dir)) { 06097 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 06098 /* Delete files */ 06099 ast_filedelete(tmptxtfile, NULL); 06100 unlink(tmptxtfile); 06101 inprocess_count(vmu->mailbox, vmu->context, -1); 06102 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06103 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06104 unlink(tmptxtfile); 06105 ast_unlock_path(dir); 06106 inprocess_count(vmu->mailbox, vmu->context, -1); 06107 if (ast_check_realtime("voicemail_data")) { 06108 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06109 } 06110 } else { 06111 #ifndef IMAP_STORAGE 06112 msgnum = last_message_index(vmu, dir) + 1; 06113 #endif 06114 make_file(fn, sizeof(fn), dir, msgnum); 06115 06116 /* assign a variable with the name of the voicemail file */ 06117 #ifndef IMAP_STORAGE 06118 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06119 #else 06120 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06121 #endif 06122 06123 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06124 ast_filerename(tmptxtfile, fn, NULL); 06125 rename(tmptxtfile, txtfile); 06126 inprocess_count(vmu->mailbox, vmu->context, -1); 06127 06128 /* Properly set permissions on voicemail text descriptor file. 06129 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06130 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06131 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06132 06133 ast_unlock_path(dir); 06134 if (ast_check_realtime("voicemail_data")) { 06135 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06136 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06137 } 06138 /* We must store the file first, before copying the message, because 06139 * ODBC storage does the entire copy with SQL. 06140 */ 06141 if (ast_fileexists(fn, NULL, NULL) > 0) { 06142 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06143 } 06144 06145 /* Are there to be more recipients of this message? */ 06146 while (tmpptr) { 06147 struct ast_vm_user recipu, *recip; 06148 char *exten, *cntx; 06149 06150 exten = strsep(&tmpptr, "&"); 06151 cntx = strchr(exten, '@'); 06152 if (cntx) { 06153 *cntx = '\0'; 06154 cntx++; 06155 } 06156 if ((recip = find_user(&recipu, cntx, exten))) { 06157 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06158 free_user(recip); 06159 } 06160 } 06161 #ifndef IMAP_STORAGE 06162 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06163 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06164 char sfn[PATH_MAX]; 06165 char dfn[PATH_MAX]; 06166 int x; 06167 /* It's easier just to try to make it than to check for its existence */ 06168 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06169 x = last_message_index(vmu, urgdir) + 1; 06170 make_file(sfn, sizeof(sfn), dir, msgnum); 06171 make_file(dfn, sizeof(dfn), urgdir, x); 06172 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06173 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06174 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06175 ast_copy_string(fn, dfn, sizeof(fn)); 06176 msgnum = x; 06177 } 06178 #endif 06179 /* Notification needs to happen after the copy, though. */ 06180 if (ast_fileexists(fn, NULL, NULL)) { 06181 #ifdef IMAP_STORAGE 06182 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06183 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06184 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06185 flag); 06186 #else 06187 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06188 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06189 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06190 flag); 06191 #endif 06192 } 06193 06194 /* Disposal needs to happen after the optional move and copy */ 06195 if (ast_fileexists(fn, NULL, NULL)) { 06196 DISPOSE(dir, msgnum); 06197 } 06198 } 06199 } 06200 } else { 06201 inprocess_count(vmu->mailbox, vmu->context, -1); 06202 } 06203 if (res == '0') { 06204 goto transfer; 06205 } else if (res > 0 && res != 't') 06206 res = 0; 06207 06208 if (sound_duration < vmu->minsecs) 06209 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06210 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06211 else 06212 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06213 } else 06214 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06215 leave_vm_out: 06216 free_user(vmu); 06217 06218 #ifdef IMAP_STORAGE 06219 /* expunge message - use UID Expunge if supported on IMAP server*/ 06220 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06221 if (expungeonhangup == 1) { 06222 ast_mutex_lock(&vms->lock); 06223 #ifdef HAVE_IMAP_TK2006 06224 if (LEVELUIDPLUS (vms->mailstream)) { 06225 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06226 } else 06227 #endif 06228 mail_expunge(vms->mailstream); 06229 ast_mutex_unlock(&vms->lock); 06230 } 06231 #endif 06232 06233 ast_free(tmp); 06234 return res; 06235 }
| static int load_config | ( | int | reload | ) | [static] |
Definition at line 11974 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.
11975 { 11976 struct ast_config *cfg, *ucfg; 11977 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11978 int res; 11979 11980 ast_unload_realtime("voicemail"); 11981 ast_unload_realtime("voicemail_data"); 11982 11983 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11984 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11985 return 0; 11986 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11987 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11988 ucfg = NULL; 11989 } 11990 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11991 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11992 ast_config_destroy(ucfg); 11993 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11994 return 0; 11995 } 11996 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11997 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11998 return 0; 11999 } else { 12000 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 12001 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 12002 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 12003 ucfg = NULL; 12004 } 12005 } 12006 12007 res = actual_load_config(reload, cfg, ucfg); 12008 12009 ast_config_destroy(cfg); 12010 ast_config_destroy(ucfg); 12011 12012 return res; 12013 }
| static int load_module | ( | void | ) | [static] |
Definition at line 13349 of file app_voicemail.c.
References ao2_container_alloc, 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, RQ_CHAR, RQ_UINTEGER3, sayname(), SENTINEL, vm_box_exists(), vm_data_providers, vm_exec(), vm_execmain(), vm_info_acf, vmauthenticate(), and vmsayname_exec().
13350 { 13351 int res; 13352 my_umask = umask(0); 13353 umask(my_umask); 13354 13355 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13356 return AST_MODULE_LOAD_DECLINE; 13357 } 13358 13359 /* compute the location of the voicemail spool directory */ 13360 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13361 13362 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13363 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13364 } 13365 13366 if ((res = load_config(0))) 13367 return res; 13368 13369 res = ast_register_application_xml(app, vm_exec); 13370 res |= ast_register_application_xml(app2, vm_execmain); 13371 res |= ast_register_application_xml(app3, vm_box_exists); 13372 res |= ast_register_application_xml(app4, vmauthenticate); 13373 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13374 res |= ast_custom_function_register(&mailbox_exists_acf); 13375 res |= ast_custom_function_register(&vm_info_acf); 13376 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13377 #ifdef TEST_FRAMEWORK 13378 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13379 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13380 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13381 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13382 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13383 res |= AST_TEST_REGISTER(test_voicemail_vm_info); 13384 #endif 13385 13386 if (res) 13387 return res; 13388 13389 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13390 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13391 13392 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13393 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13394 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13395 13396 return res; 13397 }
| 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 |
Definition at line 1734 of file app_voicemail.c.
01735 { 01736 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01737 }
| 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 4615 of file app_voicemail.c.
References add_email_attachment(), ast_channel_name(), 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_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(), VM_PBXSKIP, and vmu_tm().
Referenced by sendmail().
04616 { 04617 char date[256]; 04618 char host[MAXHOSTNAMELEN] = ""; 04619 char who[256]; 04620 char bound[256]; 04621 char dur[256]; 04622 struct ast_tm tm; 04623 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04624 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04625 char *greeting_attachment; 04626 char filename[256]; 04627 04628 if (!str1 || !str2) { 04629 ast_free(str1); 04630 ast_free(str2); 04631 return; 04632 } 04633 04634 if (cidnum) { 04635 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04636 } 04637 if (cidname) { 04638 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04639 } 04640 gethostname(host, sizeof(host) - 1); 04641 04642 if (strchr(srcemail, '@')) { 04643 ast_copy_string(who, srcemail, sizeof(who)); 04644 } else { 04645 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04646 } 04647 04648 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04649 if (greeting_attachment) { 04650 *greeting_attachment++ = '\0'; 04651 } 04652 04653 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04654 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04655 fprintf(p, "Date: %s" ENDL, date); 04656 04657 /* Set date format for voicemail mail */ 04658 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04659 04660 if (!ast_strlen_zero(fromstring)) { 04661 struct ast_channel *ast; 04662 if ((ast = ast_dummy_channel_alloc())) { 04663 char *ptr; 04664 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04665 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04666 04667 if (check_mime(ast_str_buffer(str1))) { 04668 int first_line = 1; 04669 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04670 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04671 *ptr = '\0'; 04672 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04673 first_line = 0; 04674 /* Substring is smaller, so this will never grow */ 04675 ast_str_set(&str2, 0, "%s", ptr + 1); 04676 } 04677 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04678 } else { 04679 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04680 } 04681 ast = ast_channel_unref(ast); 04682 } else { 04683 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04684 } 04685 } else { 04686 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04687 } 04688 04689 if (check_mime(vmu->fullname)) { 04690 int first_line = 1; 04691 char *ptr; 04692 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04693 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04694 *ptr = '\0'; 04695 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04696 first_line = 0; 04697 /* Substring is smaller, so this will never grow */ 04698 ast_str_set(&str2, 0, "%s", ptr + 1); 04699 } 04700 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04701 } else { 04702 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04703 } 04704 04705 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04706 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04707 struct ast_channel *ast; 04708 if ((ast = ast_dummy_channel_alloc())) { 04709 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04710 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04711 if (check_mime(ast_str_buffer(str1))) { 04712 int first_line = 1; 04713 char *ptr; 04714 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04715 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04716 *ptr = '\0'; 04717 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04718 first_line = 0; 04719 /* Substring is smaller, so this will never grow */ 04720 ast_str_set(&str2, 0, "%s", ptr + 1); 04721 } 04722 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04723 } else { 04724 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04725 } 04726 ast = ast_channel_unref(ast); 04727 } else { 04728 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04729 } 04730 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04731 if (ast_strlen_zero(flag)) { 04732 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04733 } else { 04734 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04735 } 04736 } else { 04737 if (ast_strlen_zero(flag)) { 04738 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04739 } else { 04740 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04741 } 04742 } 04743 04744 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04745 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04746 if (imap) { 04747 /* additional information needed for IMAP searching */ 04748 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04749 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04750 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04751 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04752 #ifdef IMAP_STORAGE 04753 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04754 #else 04755 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04756 #endif 04757 /* flag added for Urgent */ 04758 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04759 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04760 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, ast_channel_name(chan)); 04761 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04762 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04763 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04764 if (!ast_strlen_zero(category)) { 04765 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04766 } else { 04767 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04768 } 04769 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04770 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04771 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04772 } 04773 if (!ast_strlen_zero(cidnum)) { 04774 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04775 } 04776 if (!ast_strlen_zero(cidname)) { 04777 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04778 } 04779 fprintf(p, "MIME-Version: 1.0" ENDL); 04780 if (attach_user_voicemail) { 04781 /* Something unique. */ 04782 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04783 (int) getpid(), (unsigned int) ast_random()); 04784 04785 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04786 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04787 fprintf(p, "--%s" ENDL, bound); 04788 } 04789 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04790 if (emailbody || vmu->emailbody) { 04791 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04792 struct ast_channel *ast; 04793 if ((ast = ast_dummy_channel_alloc())) { 04794 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04795 ast_str_substitute_variables(&str1, 0, ast, e_body); 04796 #ifdef IMAP_STORAGE 04797 { 04798 /* Convert body to native line terminators for IMAP backend */ 04799 char *line = ast_str_buffer(str1), *next; 04800 do { 04801 /* Terminate line before outputting it to the file */ 04802 if ((next = strchr(line, '\n'))) { 04803 *next++ = '\0'; 04804 } 04805 fprintf(p, "%s" ENDL, line); 04806 line = next; 04807 } while (!ast_strlen_zero(line)); 04808 } 04809 #else 04810 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04811 #endif 04812 ast = ast_channel_unref(ast); 04813 } else { 04814 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04815 } 04816 } else if (msgnum > -1) { 04817 if (strcmp(vmu->mailbox, mailbox)) { 04818 /* Forwarded type */ 04819 struct ast_config *msg_cfg; 04820 const char *v; 04821 int inttime; 04822 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04823 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04824 /* Retrieve info from VM attribute file */ 04825 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04826 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04827 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04828 strcat(fromfile, ".txt"); 04829 } 04830 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04831 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04832 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04833 } 04834 04835 /* You might be tempted to do origdate, except that a) it's in the wrong 04836 * format, and b) it's missing for IMAP recordings. */ 04837 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04838 struct timeval tv = { inttime, }; 04839 struct ast_tm tm; 04840 ast_localtime(&tv, &tm, NULL); 04841 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04842 } 04843 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04844 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04845 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04846 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04847 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04848 date, origcallerid, origdate); 04849 ast_config_destroy(msg_cfg); 04850 } else { 04851 goto plain_message; 04852 } 04853 } else { 04854 plain_message: 04855 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04856 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04857 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04858 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04859 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04860 } 04861 } else { 04862 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04863 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04864 } 04865 04866 if (imap || attach_user_voicemail) { 04867 if (!ast_strlen_zero(attach2)) { 04868 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04869 ast_debug(5, "creating second attachment filename %s\n", filename); 04870 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04871 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04872 ast_debug(5, "creating attachment filename %s\n", filename); 04873 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04874 } else { 04875 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04876 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04877 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04878 } 04879 } 04880 ast_free(str1); 04881 ast_free(str2); 04882 }
| 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 |
Definition at line 1751 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().
01752 { 01753 return snprintf(dest, len, "%s/msg%04d", dir, num); 01754 }
| static int manager_list_voicemail_users | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Manager list voicemail users command.
Definition at line 11798 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, ast_vm_user::mailcmd, make_dir(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::pager, RESULT_SUCCESS, ast_vm_user::saydurationm, 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().
11799 { 11800 struct ast_vm_user *vmu = NULL; 11801 const char *id = astman_get_header(m, "ActionID"); 11802 char actionid[128] = ""; 11803 11804 if (!ast_strlen_zero(id)) 11805 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11806 11807 AST_LIST_LOCK(&users); 11808 11809 if (AST_LIST_EMPTY(&users)) { 11810 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11811 AST_LIST_UNLOCK(&users); 11812 return RESULT_SUCCESS; 11813 } 11814 11815 astman_send_ack(s, m, "Voicemail user list will follow"); 11816 11817 AST_LIST_TRAVERSE(&users, vmu, list) { 11818 char dirname[256]; 11819 11820 #ifdef IMAP_STORAGE 11821 int new, old; 11822 inboxcount(vmu->mailbox, &new, &old); 11823 #endif 11824 11825 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11826 astman_append(s, 11827 "%s" 11828 "Event: VoicemailUserEntry\r\n" 11829 "VMContext: %s\r\n" 11830 "VoiceMailbox: %s\r\n" 11831 "Fullname: %s\r\n" 11832 "Email: %s\r\n" 11833 "Pager: %s\r\n" 11834 "ServerEmail: %s\r\n" 11835 "MailCommand: %s\r\n" 11836 "Language: %s\r\n" 11837 "TimeZone: %s\r\n" 11838 "Callback: %s\r\n" 11839 "Dialout: %s\r\n" 11840 "UniqueID: %s\r\n" 11841 "ExitContext: %s\r\n" 11842 "SayDurationMinimum: %d\r\n" 11843 "SayEnvelope: %s\r\n" 11844 "SayCID: %s\r\n" 11845 "AttachMessage: %s\r\n" 11846 "AttachmentFormat: %s\r\n" 11847 "DeleteMessage: %s\r\n" 11848 "VolumeGain: %.2f\r\n" 11849 "CanReview: %s\r\n" 11850 "CallOperator: %s\r\n" 11851 "MaxMessageCount: %d\r\n" 11852 "MaxMessageLength: %d\r\n" 11853 "NewMessageCount: %d\r\n" 11854 #ifdef IMAP_STORAGE 11855 "OldMessageCount: %d\r\n" 11856 "IMAPUser: %s\r\n" 11857 "IMAPServer: %s\r\n" 11858 "IMAPPort: %s\r\n" 11859 "IMAPFlags: %s\r\n" 11860 #endif 11861 "\r\n", 11862 actionid, 11863 vmu->context, 11864 vmu->mailbox, 11865 vmu->fullname, 11866 vmu->email, 11867 vmu->pager, 11868 vmu->serveremail, 11869 vmu->mailcmd, 11870 vmu->language, 11871 vmu->zonetag, 11872 vmu->callback, 11873 vmu->dialout, 11874 vmu->uniqueid, 11875 vmu->exit, 11876 vmu->saydurationm, 11877 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11878 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11879 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11880 vmu->attachfmt, 11881 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11882 vmu->volgain, 11883 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11884 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11885 vmu->maxmsg, 11886 vmu->maxsecs, 11887 #ifdef IMAP_STORAGE 11888 new, old, 11889 vmu->imapuser, 11890 vmu->imapserver, 11891 vmu->imapport, 11892 vmu->imapflags 11893 #else 11894 count_messages(vmu, dirname) 11895 #endif 11896 ); 11897 } 11898 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11899 11900 AST_LIST_UNLOCK(&users); 11901 11902 return RESULT_SUCCESS; 11903 }
| static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11632 of file app_voicemail.c.
References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), poll_lock, and poll_subscribed_mailboxes().
Referenced by start_poll_thread().
11633 { 11634 while (poll_thread_run) { 11635 struct timespec ts = { 0, }; 11636 struct timeval wait; 11637 11638 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11639 ts.tv_sec = wait.tv_sec; 11640 ts.tv_nsec = wait.tv_usec * 1000; 11641 11642 ast_mutex_lock(&poll_lock); 11643 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11644 ast_mutex_unlock(&poll_lock); 11645 11646 if (!poll_thread_run) 11647 break; 11648 11649 poll_subscribed_mailboxes(); 11650 } 11651 11652 return NULL; 11653 }
| static const char* mbox | ( | struct ast_vm_user * | vmu, | |
| int | id | |||
| ) | [static] |
Definition at line 1812 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().
01813 { 01814 #ifdef IMAP_STORAGE 01815 if (vmu && id == 0) { 01816 return vmu->imapfolder; 01817 } 01818 #endif 01819 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01820 }
| static int messagecount | ( | const char * | context, | |
| const char * | mailbox, | |||
| const char * | folder | |||
| ) | [static] |
Definition at line 5469 of file app_voicemail.c.
References __has_voicemail().
Referenced by acf_vm_info(), and load_module().
05470 { 05471 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05472 }
| static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11655 of file app_voicemail.c.
References ast_free.
Referenced by handle_unsubscribe().
11656 { 11657 ast_free(mwi_sub); 11658 }
| static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 11733 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().
11734 { 11735 struct mwi_sub_task *mwist; 11736 11737 if (ast_event_get_type(event) != AST_EVENT_SUB) 11738 return; 11739 11740 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11741 return; 11742 11743 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11744 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11745 return; 11746 } 11747 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11748 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11749 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11750 11751 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11752 ast_free(mwist); 11753 } 11754 }
| static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 11717 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_taskprocessor_push(), handle_unsubscribe(), mwi_subscription_tps, and mwi_sub_task::uniqueid.
Referenced by start_poll_thread().
11718 { 11719 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11720 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 11721 return; 11722 11723 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11724 return; 11725 11726 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11727 *uniqueid = u; 11728 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11729 ast_free(uniqueid); 11730 } 11731 }
| 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 7133 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, strsep(), VM_ATTACH, vm_delete(), and VM_DELETE.
07134 { 07135 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07136 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07137 const char *category; 07138 char *myserveremail = serveremail; 07139 07140 ast_channel_lock(chan); 07141 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07142 category = ast_strdupa(category); 07143 } 07144 ast_channel_unlock(chan); 07145 07146 #ifndef IMAP_STORAGE 07147 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07148 #else 07149 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07150 #endif 07151 make_file(fn, sizeof(fn), todir, msgnum); 07152 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07153 07154 if (!ast_strlen_zero(vmu->attachfmt)) { 07155 if (strstr(fmt, vmu->attachfmt)) 07156 fmt = vmu->attachfmt; 07157 else 07158 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); 07159 } 07160 07161 /* Attach only the first format */ 07162 fmt = ast_strdupa(fmt); 07163 stringp = fmt; 07164 strsep(&stringp, "|"); 07165 07166 if (!ast_strlen_zero(vmu->serveremail)) 07167 myserveremail = vmu->serveremail; 07168 07169 if (!ast_strlen_zero(vmu->email)) { 07170 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07171 07172 if (attach_user_voicemail) 07173 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07174 07175 /* XXX possible imap issue, should category be NULL XXX */ 07176 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07177 07178 if (attach_user_voicemail) 07179 DISPOSE(todir, msgnum); 07180 } 07181 07182 if (!ast_strlen_zero(vmu->pager)) { 07183 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07184 } 07185 07186 if (ast_test_flag(vmu, VM_DELETE)) 07187 DELETE(todir, msgnum, fn, vmu); 07188 07189 /* Leave voicemail for someone */ 07190 if (ast_app_has_voicemail(ext_context, NULL)) 07191 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07192 07193 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07194 07195 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); 07196 run_externnotify(vmu->context, vmu->mailbox, flag); 07197 07198 #ifdef IMAP_STORAGE 07199 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07200 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07201 vm_imap_delete(NULL, vms->curmsg, vmu); 07202 vms->newmessages--; /* Fix new message count */ 07203 } 07204 #endif 07205 07206 return 0; 07207 }
| static int ochar | ( | struct baseio * | bio, | |
| int | c, | |||
| FILE * | so | |||
| ) | [static] |
utility used by base_encode()
Definition at line 4337 of file app_voicemail.c.
References BASELINELEN, ENDL, and baseio::linelength.
Referenced by base_encode().
04338 { 04339 if (bio->linelength >= BASELINELEN) { 04340 if (fputs(ENDL, so) == EOF) { 04341 return -1; 04342 } 04343 04344 bio->linelength = 0; 04345 } 04346 04347 if (putc(((unsigned char) c), so) == EOF) { 04348 return -1; 04349 } 04350 04351 bio->linelength++; 04352 04353 return 1; 04354 }
| static int open_mailbox | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu, | |||
| int | box | |||
| ) | [static] |
Definition at line 7991 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().
07992 { 07993 int count_msg, last_msg; 07994 07995 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07996 07997 /* Rename the member vmbox HERE so that we don't try to return before 07998 * we know what's going on. 07999 */ 08000 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 08001 08002 /* Faster to make the directory than to check if it exists. */ 08003 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 08004 08005 /* traverses directory using readdir (or select query for ODBC) */ 08006 count_msg = count_messages(vmu, vms->curdir); 08007 if (count_msg < 0) { 08008 return count_msg; 08009 } else { 08010 vms->lastmsg = count_msg - 1; 08011 } 08012 08013 if (vm_allocate_dh(vms, vmu, count_msg)) { 08014 return -1; 08015 } 08016 08017 /* 08018 The following test is needed in case sequencing gets messed up. 08019 There appears to be more than one way to mess up sequence, so 08020 we will not try to find all of the root causes--just fix it when 08021 detected. 08022 */ 08023 08024 if (vm_lock_path(vms->curdir)) { 08025 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 08026 return ERROR_LOCK_PATH; 08027 } 08028 08029 /* for local storage, checks directory for messages up to maxmsg limit */ 08030 last_msg = last_message_index(vmu, vms->curdir); 08031 ast_unlock_path(vms->curdir); 08032 08033 if (last_msg < -1) { 08034 return last_msg; 08035 } else if (vms->lastmsg != last_msg) { 08036 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); 08037 resequence_mailbox(vmu, vms->curdir, count_msg); 08038 } 08039 08040 return 0; 08041 }
| static int play_message | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7769 of file app_voicemail.c.
References adsi_message(), ast_channel_language(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, CONFIG_STATUS_FILEINVALID, 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, 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().
07770 { 07771 int res = 0; 07772 char filename[256], *cid; 07773 const char *origtime, *context, *category, *duration, *flag; 07774 struct ast_config *msg_cfg; 07775 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07776 07777 vms->starting = 0; 07778 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07779 adsi_message(chan, vms); 07780 if (!vms->curmsg) { 07781 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07782 } else if (vms->curmsg == vms->lastmsg) { 07783 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07784 } 07785 07786 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07787 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07788 msg_cfg = ast_config_load(filename, config_flags); 07789 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07790 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07791 return 0; 07792 } 07793 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07794 07795 /* Play the word urgent if we are listening to urgent messages */ 07796 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07797 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07798 } 07799 07800 if (!res) { 07801 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07802 /* POLISH syntax */ 07803 if (!strncasecmp(ast_channel_language(chan), "pl", 2)) { 07804 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07805 int ten, one; 07806 char nextmsg[256]; 07807 ten = (vms->curmsg + 1) / 10; 07808 one = (vms->curmsg + 1) % 10; 07809 07810 if (vms->curmsg < 20) { 07811 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07812 res = wait_file2(chan, vms, nextmsg); 07813 } else { 07814 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07815 res = wait_file2(chan, vms, nextmsg); 07816 if (one > 0) { 07817 if (!res) { 07818 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07819 res = wait_file2(chan, vms, nextmsg); 07820 } 07821 } 07822 } 07823 } 07824 if (!res) 07825 res = wait_file2(chan, vms, "vm-message"); 07826 /* HEBREW syntax */ 07827 } else if (!strncasecmp(ast_channel_language(chan), "he", 2)) { 07828 if (!vms->curmsg) { 07829 res = wait_file2(chan, vms, "vm-message"); 07830 res = wait_file2(chan, vms, "vm-first"); 07831 } else if (vms->curmsg == vms->lastmsg) { 07832 res = wait_file2(chan, vms, "vm-message"); 07833 res = wait_file2(chan, vms, "vm-last"); 07834 } else { 07835 res = wait_file2(chan, vms, "vm-message"); 07836 res = wait_file2(chan, vms, "vm-number"); 07837 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, ast_channel_language(chan), "f"); 07838 } 07839 /* VIETNAMESE syntax */ 07840 } else if (!strncasecmp(ast_channel_language(chan), "vi", 2)) { 07841 if (!vms->curmsg) { 07842 res = wait_file2(chan, vms, "vm-message"); 07843 res = wait_file2(chan, vms, "vm-first"); 07844 } else if (vms->curmsg == vms->lastmsg) { 07845 res = wait_file2(chan, vms, "vm-message"); 07846 res = wait_file2(chan, vms, "vm-last"); 07847 } else { 07848 res = wait_file2(chan, vms, "vm-message"); 07849 res = wait_file2(chan, vms, "vm-number"); 07850 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, ast_channel_language(chan), "f"); 07851 } 07852 } else { 07853 if (!strncasecmp(ast_channel_language(chan), "se", 2)) { /* SWEDISH syntax */ 07854 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07855 } else { /* DEFAULT syntax */ 07856 res = wait_file2(chan, vms, "vm-message"); 07857 } 07858 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07859 if (!res) { 07860 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07861 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, ast_channel_language(chan), NULL); 07862 } 07863 } 07864 } 07865 } 07866 07867 if (!msg_cfg) { 07868 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07869 return 0; 07870 } 07871 07872 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07873 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07874 DISPOSE(vms->curdir, vms->curmsg); 07875 ast_config_destroy(msg_cfg); 07876 return 0; 07877 } 07878 07879 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07880 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07881 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07882 07883 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07884 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07885 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07886 if (!res) { 07887 res = play_message_category(chan, category); 07888 } 07889 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07890 res = play_message_datetime(chan, vmu, origtime, filename); 07891 } 07892 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07893 res = play_message_callerid(chan, vms, cid, context, 0, 0); 07894 } 07895 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07896 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07897 } 07898 /* Allow pressing '1' to skip envelope / callerid */ 07899 if (res == '1') { 07900 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07901 res = 0; 07902 } 07903 ast_config_destroy(msg_cfg); 07904 07905 if (!res) { 07906 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07907 vms->heard[vms->curmsg] = 1; 07908 #ifdef IMAP_STORAGE 07909 /*IMAP storage stores any prepended message from a forward 07910 * as a separate file from the rest of the message 07911 */ 07912 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07913 wait_file(chan, vms, vms->introfn); 07914 } 07915 #endif 07916 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07917 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07918 res = 0; 07919 } 07920 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07921 } 07922 DISPOSE(vms->curdir, vms->curmsg); 07923 return res; 07924 }
| static int play_message_callerid | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | cid, | |||
| const char * | context, | |||
| int | callback, | |||
| int | saycidnumber | |||
| ) | [static] |
Definition at line 7642 of file app_voicemail.c.
References ast_callerid_parse(), ast_channel_language(), ast_config_AST_SPOOL_DIR, 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, and wait_file2().
Referenced by advanced_options(), and play_message().
07643 { 07644 int res = 0; 07645 int i; 07646 char *callerid, *name; 07647 char prefile[PATH_MAX] = ""; 07648 07649 /* If voicemail cid is not enabled, or we didn't get cid or context from 07650 * the attribute file, leave now. 07651 * 07652 * TODO Still need to change this so that if this function is called by the 07653 * message envelope (and someone is explicitly requesting to hear the CID), 07654 * it does not check to see if CID is enabled in the config file. 07655 */ 07656 if ((cid == NULL)||(context == NULL)) 07657 return res; 07658 07659 /* Strip off caller ID number from name */ 07660 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07661 ast_callerid_parse(cid, &name, &callerid); 07662 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07663 /* Check for internal contexts and only */ 07664 /* say extension when the call didn't come from an internal context in the list */ 07665 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07666 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07667 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07668 break; 07669 } 07670 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07671 if (!res) { 07672 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07673 if (!ast_strlen_zero(prefile)) { 07674 /* See if we can find a recorded name for this callerid 07675 * and if found, use that instead of saying number. */ 07676 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07677 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07678 if (!callback) 07679 res = wait_file2(chan, vms, "vm-from"); 07680 res = ast_stream_and_wait(chan, prefile, ""); 07681 } else { 07682 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07683 /* Say "from extension" as one saying to sound smoother */ 07684 if (!callback) 07685 res = wait_file2(chan, vms, "vm-from-extension"); 07686 res = ast_say_digit_str(chan, callerid, "", ast_channel_language(chan)); 07687 } 07688 } 07689 } 07690 } else if (!res) { 07691 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07692 /* If there is a recording for this numeric callerid then play that */ 07693 if (!callback) { 07694 /* See if we can find a recorded name for this person instead of their extension number */ 07695 snprintf(prefile, sizeof(prefile), "%s/recordings/callerids/%s", ast_config_AST_SPOOL_DIR, callerid); 07696 if (!saycidnumber && ast_fileexists(prefile, NULL, NULL) > 0) { 07697 ast_verb(3, "Playing recorded name for CID number '%s' - '%s'\n", callerid,prefile); 07698 wait_file2(chan, vms, "vm-from"); 07699 res = ast_stream_and_wait(chan, prefile, ""); 07700 ast_verb(3, "Played recorded name result '%d'\n", res); 07701 } else { 07702 /* Since this is all nicely figured out, why not say "from phone number" in this case" */ 07703 wait_file2(chan, vms, "vm-from-phonenumber"); 07704 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, ast_channel_language(chan)); 07705 } 07706 } else { 07707 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, ast_channel_language(chan)); 07708 } 07709 } 07710 } else { 07711 /* Number unknown */ 07712 ast_debug(1, "VM-CID: From an unknown number\n"); 07713 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07714 res = wait_file2(chan, vms, "vm-unknown-caller"); 07715 } 07716 return res; 07717 }
| static int play_message_category | ( | struct ast_channel * | chan, | |
| const char * | category | |||
| ) | [static] |
Definition at line 7553 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
07554 { 07555 int res = 0; 07556 07557 if (!ast_strlen_zero(category)) 07558 res = ast_play_and_wait(chan, category); 07559 07560 if (res) { 07561 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07562 res = 0; 07563 } 07564 07565 return res; 07566 }
| static int play_message_datetime | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| const char * | origtime, | |||
| const char * | filename | |||
| ) | [static] |
Definition at line 7568 of file app_voicemail.c.
References ast_channel_language(), 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(), vm_zone::msg_format, vm_zone::name, pbx_builtin_setvar_helper(), vm_zone::timezone, and ast_vm_user::zonetag.
Referenced by advanced_options(), and play_message().
07569 { 07570 int res = 0; 07571 struct vm_zone *the_zone = NULL; 07572 time_t t; 07573 07574 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07575 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07576 return 0; 07577 } 07578 07579 /* Does this user have a timezone specified? */ 07580 if (!ast_strlen_zero(vmu->zonetag)) { 07581 /* Find the zone in the list */ 07582 struct vm_zone *z; 07583 AST_LIST_LOCK(&zones); 07584 AST_LIST_TRAVERSE(&zones, z, list) { 07585 if (!strcmp(z->name, vmu->zonetag)) { 07586 the_zone = z; 07587 break; 07588 } 07589 } 07590 AST_LIST_UNLOCK(&zones); 07591 } 07592 07593 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07594 #if 0 07595 /* Set the DIFF_* variables */ 07596 ast_localtime(&t, &time_now, NULL); 07597 tv_now = ast_tvnow(); 07598 ast_localtime(&tv_now, &time_then, NULL); 07599 07600 /* Day difference */ 07601 if (time_now.tm_year == time_then.tm_year) 07602 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07603 else 07604 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07605 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07606 07607 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07608 #endif 07609 if (the_zone) { 07610 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), the_zone->msg_format, the_zone->timezone); 07611 } else if (!strncasecmp(ast_channel_language(chan), "de", 2)) { /* GERMAN syntax */ 07612 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' Q 'digits/at' HM", NULL); 07613 } else if (!strncasecmp(ast_channel_language(chan), "gr", 2)) { /* GREEK syntax */ 07614 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q H 'digits/kai' M ", NULL); 07615 } else if (!strncasecmp(ast_channel_language(chan), "it", 2)) { /* ITALIAN syntax */ 07616 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q 'digits/at' 'digits/hours' k 'digits/e' M 'digits/minutes'", NULL); 07617 } else if (!strncasecmp(ast_channel_language(chan), "nl", 2)) { /* DUTCH syntax */ 07618 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q 'digits/nl-om' HM", NULL); 07619 } else if (!strncasecmp(ast_channel_language(chan), "no", 2)) { /* NORWEGIAN syntax */ 07620 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' Q 'digits/at' HM", NULL); 07621 } else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) { /* POLISH syntax */ 07622 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' Q HM", NULL); 07623 } else if (!strncasecmp(ast_channel_language(chan), "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07624 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' Ad 'digits/pt-de' B 'digits/pt-de' Y 'digits/pt-as' HM ", NULL); 07625 } else if (!strncasecmp(ast_channel_language(chan), "se", 2)) { /* SWEDISH syntax */ 07626 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' dB 'digits/at' k 'and' M", NULL); 07627 } else if (!strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07628 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "qR 'vm-received'", NULL); 07629 } else if (!strncasecmp(ast_channel_language(chan), "vi", 2)) { /* VIETNAMESE syntax */ 07630 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' A 'digits/day' dB 'digits/year' Y 'digits/at' k 'hours' M 'minutes'", NULL); 07631 } else { 07632 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q 'digits/at' IMp", NULL); 07633 } 07634 #if 0 07635 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07636 #endif 07637 return res; 07638 }
| static int play_message_duration | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| const char * | duration, | |||
| int | minduration | |||
| ) | [static] |
Definition at line 7719 of file app_voicemail.c.
References ast_channel_language(), ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), say_and_wait(), and wait_file2().
Referenced by play_message().
07720 { 07721 int res = 0; 07722 int durationm; 07723 int durations; 07724 /* Verify that we have a duration for the message */ 07725 if (duration == NULL) 07726 return res; 07727 07728 /* Convert from seconds to minutes */ 07729 durations = atoi(duration); 07730 durationm = (durations / 60); 07731 07732 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07733 07734 if ((!res) && (durationm >= minduration)) { 07735 res = wait_file2(chan, vms, "vm-duration"); 07736 07737 /* POLISH syntax */ 07738 if (!strncasecmp(ast_channel_language(chan), "pl", 2)) { 07739 div_t num = div(durationm, 10); 07740 07741 if (durationm == 1) { 07742 res = ast_play_and_wait(chan, "digits/1z"); 07743 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07744 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07745 if (num.rem == 2) { 07746 if (!num.quot) { 07747 res = ast_play_and_wait(chan, "digits/2-ie"); 07748 } else { 07749 res = say_and_wait(chan, durationm - 2 , ast_channel_language(chan)); 07750 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07751 } 07752 } else { 07753 res = say_and_wait(chan, durationm, ast_channel_language(chan)); 07754 } 07755 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07756 } else { 07757 res = say_and_wait(chan, durationm, ast_channel_language(chan)); 07758 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07759 } 07760 /* DEFAULT syntax */ 07761 } else { 07762 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, ast_channel_language(chan), NULL); 07763 res = wait_file2(chan, vms, "vm-minutes"); 07764 } 07765 } 07766 return res; 07767 }
| 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 13664 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_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, INTRO, ast_vm_user::mailbox, STORE, vm_exec(), VM_OPERATOR, and VM_REVIEW.
13667 { 13668 /* Record message & let caller review or re-record it, or set options if applicable */ 13669 int res = 0; 13670 int cmd = 0; 13671 int max_attempts = 3; 13672 int attempts = 0; 13673 int recorded = 0; 13674 int msg_exists = 0; 13675 signed char zero_gain = 0; 13676 char tempfile[PATH_MAX]; 13677 char *acceptdtmf = "#"; 13678 char *canceldtmf = ""; 13679 int canceleddtmf = 0; 13680 13681 /* Note that urgent and private are for flagging messages as such in the future */ 13682 13683 /* barf if no pointer passed to store duration in */ 13684 if (duration == NULL) { 13685 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13686 return -1; 13687 } 13688 13689 if (!outsidecaller) 13690 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13691 else 13692 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13693 13694 cmd = '3'; /* Want to start by recording */ 13695 13696 while ((cmd >= 0) && (cmd != 't')) { 13697 switch (cmd) { 13698 case '1': 13699 if (!msg_exists) { 13700 /* In this case, 1 is to record a message */ 13701 cmd = '3'; 13702 break; 13703 } else { 13704 /* Otherwise 1 is to save the existing message */ 13705 ast_verb(3, "Saving message as is\n"); 13706 if (!outsidecaller) 13707 ast_filerename(tempfile, recordfile, NULL); 13708 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13709 if (!outsidecaller) { 13710 /* Saves to IMAP server only if imapgreeting=yes */ 13711 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13712 DISPOSE(recordfile, -1); 13713 } 13714 cmd = 't'; 13715 return res; 13716 } 13717 case '2': 13718 /* Review */ 13719 ast_verb(3, "Reviewing the message\n"); 13720 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13721 break; 13722 case '3': 13723 msg_exists = 0; 13724 /* Record */ 13725 if (recorded == 1) 13726 ast_verb(3, "Re-recording the message\n"); 13727 else 13728 ast_verb(3, "Recording the message\n"); 13729 13730 if (recorded && outsidecaller) { 13731 cmd = ast_play_and_wait(chan, INTRO); 13732 cmd = ast_play_and_wait(chan, "beep"); 13733 } 13734 recorded = 1; 13735 /* 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 */ 13736 if (record_gain) 13737 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13738 if (ast_test_flag(vmu, VM_OPERATOR)) 13739 canceldtmf = "0"; 13740 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13741 if (strchr(canceldtmf, cmd)) { 13742 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13743 canceleddtmf = 1; 13744 } 13745 if (record_gain) 13746 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13747 if (cmd == -1) { 13748 /* User has hung up, no options to give */ 13749 if (!outsidecaller) { 13750 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13751 ast_filedelete(tempfile, NULL); 13752 } 13753 return cmd; 13754 } 13755 if (cmd == '0') { 13756 break; 13757 } else if (cmd == '*') { 13758 break; 13759 #if 0 13760 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13761 /* Message is too short */ 13762 ast_verb(3, "Message too short\n"); 13763 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13764 cmd = ast_filedelete(tempfile, NULL); 13765 break; 13766 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13767 /* Message is all silence */ 13768 ast_verb(3, "Nothing recorded\n"); 13769 cmd = ast_filedelete(tempfile, NULL); 13770 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13771 if (!cmd) 13772 cmd = ast_play_and_wait(chan, "vm-speakup"); 13773 break; 13774 #endif 13775 } else { 13776 /* If all is well, a message exists */ 13777 msg_exists = 1; 13778 cmd = 0; 13779 } 13780 break; 13781 case '4': 13782 if (outsidecaller) { /* only mark vm messages */ 13783 /* Mark Urgent */ 13784 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13785 ast_verb(3, "marking message as Urgent\n"); 13786 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13787 strcpy(flag, "Urgent"); 13788 } else if (flag) { 13789 ast_verb(3, "UNmarking message as Urgent\n"); 13790 res = ast_play_and_wait(chan, "vm-urgent-removed"); 13791 strcpy(flag, ""); 13792 } else { 13793 ast_play_and_wait(chan, "vm-sorry"); 13794 } 13795 cmd = 0; 13796 } else { 13797 cmd = ast_play_and_wait(chan, "vm-sorry"); 13798 } 13799 break; 13800 case '5': 13801 case '6': 13802 case '7': 13803 case '8': 13804 case '9': 13805 case '*': 13806 case '#': 13807 cmd = ast_play_and_wait(chan, "vm-sorry"); 13808 break; 13809 #if 0 13810 /* XXX Commented out for the moment because of the dangers of deleting 13811 a message while recording (can put the message numbers out of sync) */ 13812 case '*': 13813 /* Cancel recording, delete message, offer to take another message*/ 13814 cmd = ast_play_and_wait(chan, "vm-deleted"); 13815 cmd = ast_filedelete(tempfile, NULL); 13816 if (outsidecaller) { 13817 res = vm_exec(chan, NULL); 13818 return res; 13819 } 13820 else 13821 return 1; 13822 #endif 13823 case '0': 13824 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13825 cmd = ast_play_and_wait(chan, "vm-sorry"); 13826 break; 13827 } 13828 if (msg_exists || recorded) { 13829 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13830 if (!cmd) 13831 cmd = ast_waitfordigit(chan, 3000); 13832 if (cmd == '1') { 13833 ast_filerename(tempfile, recordfile, NULL); 13834 ast_play_and_wait(chan, "vm-msgsaved"); 13835 cmd = '0'; 13836 } else if (cmd == '4') { 13837 if (flag) { 13838 ast_play_and_wait(chan, "vm-marked-urgent"); 13839 strcpy(flag, "Urgent"); 13840 } 13841 ast_play_and_wait(chan, "vm-msgsaved"); 13842 cmd = '0'; 13843 } else { 13844 ast_play_and_wait(chan, "vm-deleted"); 13845 DELETE(tempfile, -1, tempfile, vmu); 13846 cmd = '0'; 13847 } 13848 } 13849 return cmd; 13850 default: 13851 /* If the caller is an ouside caller, and the review option is enabled, 13852 allow them to review the message, but let the owner of the box review 13853 their OGM's */ 13854 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13855 return cmd; 13856 if (msg_exists) { 13857 cmd = ast_play_and_wait(chan, "vm-review"); 13858 if (!cmd && outsidecaller) { 13859 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13860 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13861 } else if (flag) { 13862 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13863 } 13864 } 13865 } else { 13866 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13867 if (!cmd) 13868 cmd = ast_waitfordigit(chan, 600); 13869 } 13870 13871 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13872 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13873 if (!cmd) 13874 cmd = ast_waitfordigit(chan, 600); 13875 } 13876 #if 0 13877 if (!cmd) 13878 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13879 #endif 13880 if (!cmd) 13881 cmd = ast_waitfordigit(chan, 6000); 13882 if (!cmd) { 13883 attempts++; 13884 } 13885 if (attempts > max_attempts) { 13886 cmd = 't'; 13887 } 13888 } 13889 } 13890 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13891 /* Hang up or timeout, so delete the recording. */ 13892 ast_filedelete(tempfile, NULL); 13893 } 13894 13895 if (cmd != 't' && outsidecaller) 13896 ast_play_and_wait(chan, "vm-goodbye"); 13897 13898 return cmd; 13899 }
| static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11604 of file app_voicemail.c.
References inboxcount2(), mwi_sub::mailbox, mwi_sub::old_new, mwi_sub::old_old, mwi_sub::old_urgent, queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11605 { 11606 int new = 0, old = 0, urgent = 0; 11607 11608 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11609 11610 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11611 mwi_sub->old_urgent = urgent; 11612 mwi_sub->old_new = new; 11613 mwi_sub->old_old = old; 11614 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11615 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11616 } 11617 }
| static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11619 of file app_voicemail.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), mwi_sub::entry, mwi_sub::mailbox, and poll_subscribed_mailbox().
Referenced by mb_poll_thread().
11620 { 11621 struct mwi_sub *mwi_sub; 11622 11623 AST_RWLIST_RDLOCK(&mwi_subs); 11624 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11625 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11626 poll_subscribed_mailbox(mwi_sub); 11627 } 11628 } 11629 AST_RWLIST_UNLOCK(&mwi_subs); 11630 }
| 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 1088 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, ast_vm_user::locale, ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, saydurationminfo, ast_vm_user::volgain, and ast_vm_user::zonetag.
01089 { 01090 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 01091 vmu->passwordlocation = passwordlocation; 01092 if (saydurationminfo) { 01093 vmu->saydurationm = saydurationminfo; 01094 } 01095 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 01096 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 01097 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 01098 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 01099 ast_copy_string(vmu->locale, locale, sizeof(vmu->locale)); 01100 if (vmminsecs) { 01101 vmu->minsecs = vmminsecs; 01102 } 01103 if (vmmaxsecs) { 01104 vmu->maxsecs = vmmaxsecs; 01105 } 01106 if (maxmsg) { 01107 vmu->maxmsg = maxmsg; 01108 } 01109 if (maxdeletedmsg) { 01110 vmu->maxdeletedmsg = maxdeletedmsg; 01111 } 01112 vmu->volgain = volgain; 01113 ast_free(vmu->emailsubject); 01114 vmu->emailsubject = NULL; 01115 ast_free(vmu->emailbody); 01116 vmu->emailbody = NULL; 01117 #ifdef IMAP_STORAGE 01118 ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder)); 01119 ast_copy_string(vmu->imapserver, imapserver, sizeof(vmu->imapserver)); 01120 ast_copy_string(vmu->imapport, imapport, sizeof(vmu->imapport)); 01121 ast_copy_string(vmu->imapflags, imapflags, sizeof(vmu->imapflags)); 01122 #endif 01123 }
| 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 4425 of file app_voicemail.c.
References ast_callerid_merge(), ast_callerid_split(), ast_config_destroy(), ast_config_load, ast_debug, ast_localtime(), 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, ast_vm_user::mailbox, make_dir(), make_file(), pbx_builtin_setvar_helper(), and S_OR.
04426 { 04427 char callerid[256]; 04428 char num[12]; 04429 char fromdir[256], fromfile[256]; 04430 struct ast_config *msg_cfg; 04431 const char *origcallerid, *origtime; 04432 char origcidname[80], origcidnum[80], origdate[80]; 04433 int inttime; 04434 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04435 04436 /* Prepare variables for substitution in email body and subject */ 04437 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04438 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04439 snprintf(num, sizeof(num), "%d", msgnum); 04440 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04441 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04442 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04443 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04444 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04445 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04446 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04447 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04448 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04449 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04450 04451 /* Retrieve info from VM attribute file */ 04452 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04453 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04454 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04455 strcat(fromfile, ".txt"); 04456 } 04457 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04458 ast_debug(1, "Config load for message text file '%s' failed\n", fromfile); 04459 return; 04460 } 04461 04462 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04463 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04464 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04465 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04466 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04467 } 04468 04469 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04470 struct timeval tv = { inttime, }; 04471 struct ast_tm tm; 04472 ast_localtime(&tv, &tm, NULL); 04473 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04474 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04475 } 04476 ast_config_destroy(msg_cfg); 04477 }
| static void queue_mwi_event | ( | const char * | box, | |
| int | urgent, | |||
| int | new, | |||
| int | old | |||
| ) | [static] |
Definition at line 7096 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, ast_strlen_zero(), and strsep().
07097 { 07098 struct ast_event *event; 07099 char *mailbox, *context; 07100 07101 /* Strip off @default */ 07102 context = mailbox = ast_strdupa(box); 07103 strsep(&context, "@"); 07104 if (ast_strlen_zero(context)) 07105 context = "default"; 07106 07107 if (!(event = ast_event_new(AST_EVENT_MWI, 07108 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 07109 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 07110 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 07111 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 07112 AST_EVENT_IE_END))) { 07113 return; 07114 } 07115 07116 ast_event_queue_and_cache(event); 07117 }
| static void read_password_from_file | ( | const char * | secretfn, | |
| char * | password, | |||
| int | passwordlen | |||
| ) | [static] |
Definition at line 12704 of file app_voicemail.c.
References ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), and LOG_NOTICE.
Referenced by actual_load_config(), and append_mailbox().
12704 { 12705 struct ast_config *pwconf; 12706 struct ast_flags config_flags = { 0 }; 12707 12708 pwconf = ast_config_load(secretfn, config_flags); 12709 if (pwconf) { 12710 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12711 if (val) { 12712 ast_copy_string(password, val, passwordlen); 12713 return; 12714 } 12715 } 12716 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12717 }
| static int reload | ( | void | ) | [static] |
Definition at line 13307 of file app_voicemail.c.
References load_config().
13308 { 13309 return load_config(1); 13310 }
| 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. |
Definition at line 4094 of file app_voicemail.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
04095 { 04096 char stxt[PATH_MAX]; 04097 char dtxt[PATH_MAX]; 04098 ast_filerename(sfn, dfn, NULL); 04099 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 04100 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 04101 if (ast_check_realtime("voicemail_data")) { 04102 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 04103 } 04104 rename(stxt, dtxt); 04105 }
| static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
| char * | dir, | |||
| int | stopcount | |||
| ) | [static] |
Definition at line 6238 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().
06239 { 06240 /* we know the actual number of messages, so stop process when number is hit */ 06241 06242 int x, dest; 06243 char sfn[PATH_MAX]; 06244 char dfn[PATH_MAX]; 06245 06246 if (vm_lock_path(dir)) { 06247 return ERROR_LOCK_PATH; 06248 } 06249 06250 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06251 make_file(sfn, sizeof(sfn), dir, x); 06252 if (EXISTS(dir, x, sfn, NULL)) { 06253 06254 if (x != dest) { 06255 make_file(dfn, sizeof(dfn), dir, dest); 06256 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06257 } 06258 06259 dest++; 06260 } 06261 } 06262 ast_unlock_path(dir); 06263 06264 return dest; 06265 }
| 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 1579 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().
01580 { 01581 /* This function could be made to generate one from a database, too */ 01582 struct ast_vm_user *cur; 01583 int res = -1; 01584 AST_LIST_LOCK(&users); 01585 AST_LIST_TRAVERSE(&users, cur, list) { 01586 if ((!context || !strcasecmp(context, cur->context)) && 01587 (!strcasecmp(mailbox, cur->mailbox))) 01588 break; 01589 } 01590 if (cur) { 01591 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01592 res = 0; 01593 } 01594 AST_LIST_UNLOCK(&users); 01595 return res; 01596 }
| static void run_externnotify | ( | char * | context, | |
| char * | extension, | |||
| const char * | flag | |||
| ) | [static] |
Definition at line 5612 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, ast_smdi_mwi_message::fwd_st, inboxcount2(), and SMDI_MWI_WAIT_TIMEOUT.
05613 { 05614 char arguments[255]; 05615 char ext_context[256] = ""; 05616 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05617 struct ast_smdi_mwi_message *mwi_msg; 05618 05619 if (!ast_strlen_zero(context)) 05620 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05621 else 05622 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05623 05624 if (smdi_iface) { 05625 if (ast_app_has_voicemail(ext_context, NULL)) 05626 ast_smdi_mwi_set(smdi_iface, extension); 05627 else 05628 ast_smdi_mwi_unset(smdi_iface, extension); 05629 05630 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05631 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05632 if (!strncmp(mwi_msg->cause, "INV", 3)) 05633 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05634 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05635 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05636 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05637 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05638 } else { 05639 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05640 } 05641 } 05642 05643 if (!ast_strlen_zero(externnotify)) { 05644 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05645 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05646 } else { 05647 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05648 ast_debug(1, "Executing %s\n", arguments); 05649 ast_safe_system(arguments); 05650 } 05651 } 05652 }
| static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
| struct vm_state * | vms, | |||
| int | msg, | |||
| int | box | |||
| ) | [static] |
Definition at line 6275 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().
06276 { 06277 #ifdef IMAP_STORAGE 06278 /* we must use mbox(x) folder names, and copy the message there */ 06279 /* simple. huh? */ 06280 char sequence[10]; 06281 char mailbox[256]; 06282 int res; 06283 06284 /* get the real IMAP message number for this message */ 06285 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06286 06287 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06288 ast_mutex_lock(&vms->lock); 06289 /* if save to Old folder, put in INBOX as read */ 06290 if (box == OLD_FOLDER) { 06291 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06292 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06293 } else if (box == NEW_FOLDER) { 06294 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06295 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06296 } 06297 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06298 ast_mutex_unlock(&vms->lock); 06299 return 0; 06300 } 06301 /* Create the folder if it don't exist */ 06302 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06303 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06304 if (mail_create(vms->mailstream, mailbox) == NIL) 06305 ast_debug(5, "Folder exists.\n"); 06306 else 06307 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06308 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06309 ast_mutex_unlock(&vms->lock); 06310 return res; 06311 #else 06312 char *dir = vms->curdir; 06313 char *username = vms->username; 06314 char *context = vmu->context; 06315 char sfn[PATH_MAX]; 06316 char dfn[PATH_MAX]; 06317 char ddir[PATH_MAX]; 06318 const char *dbox = mbox(vmu, box); 06319 int x, i; 06320 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06321 06322 if (vm_lock_path(ddir)) 06323 return ERROR_LOCK_PATH; 06324 06325 x = last_message_index(vmu, ddir) + 1; 06326 06327 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06328 x--; 06329 for (i = 1; i <= x; i++) { 06330 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06331 make_file(sfn, sizeof(sfn), ddir, i); 06332 make_file(dfn, sizeof(dfn), ddir, i - 1); 06333 if (EXISTS(ddir, i, sfn, NULL)) { 06334 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06335 } else 06336 break; 06337 } 06338 } else { 06339 if (x >= vmu->maxmsg) { 06340 ast_unlock_path(ddir); 06341 return -1; 06342 } 06343 } 06344 make_file(sfn, sizeof(sfn), dir, msg); 06345 make_file(dfn, sizeof(dfn), ddir, x); 06346 if (strcmp(sfn, dfn)) { 06347 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06348 } 06349 ast_unlock_path(ddir); 06350 return 0; 06351 #endif 06352 }
| static int say_and_wait | ( | struct ast_channel * | chan, | |
| int | num, | |||
| const char * | language | |||
| ) | [static] |
Definition at line 6268 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().
06269 { 06270 int d; 06271 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06272 return d; 06273 }
| static int sayname | ( | struct ast_channel * | chan, | |
| const char * | mailbox, | |||
| const char * | context | |||
| ) | [static] |
Definition at line 12690 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, and RETRIEVE.
Referenced by load_module(), and vmsayname_exec().
12691 { 12692 int res = -1; 12693 char dir[PATH_MAX]; 12694 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12695 ast_debug(2, "About to try retrieving name file %s\n", dir); 12696 RETRIEVE(dir, -1, mailbox, context); 12697 if (ast_fileexists(dir, NULL, NULL)) { 12698 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12699 } 12700 DISPOSE(dir, -1); 12701 return res; 12702 }
| 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 4938 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, make_email_file(), strsep(), VM_ATTACH, and vm_mkftemp().
04939 { 04940 FILE *p = NULL; 04941 char tmp[80] = "/tmp/astmail-XXXXXX"; 04942 char tmp2[256]; 04943 char *stringp; 04944 04945 if (vmu && ast_strlen_zero(vmu->email)) { 04946 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04947 return(0); 04948 } 04949 04950 /* Mail only the first format */ 04951 format = ast_strdupa(format); 04952 stringp = format; 04953 strsep(&stringp, "|"); 04954 04955 if (!strcmp(format, "wav49")) 04956 format = "WAV"; 04957 ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH)); 04958 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04959 command hangs */ 04960 if ((p = vm_mkftemp(tmp)) == NULL) { 04961 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04962 return -1; 04963 } else { 04964 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04965 fclose(p); 04966 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04967 ast_safe_system(tmp2); 04968 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04969 } 04970 return 0; 04971 }
| 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 4973 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_locale(), ast_strlen_zero(), check_mime(), ENDL, ast_vm_user::fullname, ast_vm_user::locale, 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().
04974 { 04975 char enc_cidnum[256], enc_cidname[256]; 04976 char date[256]; 04977 char host[MAXHOSTNAMELEN] = ""; 04978 char who[256]; 04979 char dur[PATH_MAX]; 04980 char tmp[80] = "/tmp/astmail-XXXXXX"; 04981 char tmp2[PATH_MAX]; 04982 struct ast_tm tm; 04983 FILE *p; 04984 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04985 04986 if (!str1 || !str2) { 04987 ast_free(str1); 04988 ast_free(str2); 04989 return -1; 04990 } 04991 04992 if (cidnum) { 04993 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04994 } 04995 if (cidname) { 04996 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04997 } 04998 04999 if ((p = vm_mkftemp(tmp)) == NULL) { 05000 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 05001 ast_free(str1); 05002 ast_free(str2); 05003 return -1; 05004 } 05005 gethostname(host, sizeof(host)-1); 05006 if (strchr(srcemail, '@')) { 05007 ast_copy_string(who, srcemail, sizeof(who)); 05008 } else { 05009 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 05010 } 05011 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 05012 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 05013 fprintf(p, "Date: %s\n", date); 05014 05015 /* Reformat for custom pager format */ 05016 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 05017 05018 if (!ast_strlen_zero(pagerfromstring)) { 05019 struct ast_channel *ast; 05020 if ((ast = ast_dummy_channel_alloc())) { 05021 char *ptr; 05022 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 05023 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 05024 05025 if (check_mime(ast_str_buffer(str1))) { 05026 int first_line = 1; 05027 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 05028 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 05029 *ptr = '\0'; 05030 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 05031 first_line = 0; 05032 /* Substring is smaller, so this will never grow */ 05033 ast_str_set(&str2, 0, "%s", ptr + 1); 05034 } 05035 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 05036 } else { 05037 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 05038 } 05039 ast = ast_channel_unref(ast); 05040 } else { 05041 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05042 } 05043 } else { 05044 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 05045 } 05046 05047 if (check_mime(vmu->fullname)) { 05048 int first_line = 1; 05049 char *ptr; 05050 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 05051 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 05052 *ptr = '\0'; 05053 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 05054 first_line = 0; 05055 /* Substring is smaller, so this will never grow */ 05056 ast_str_set(&str2, 0, "%s", ptr + 1); 05057 } 05058 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 05059 } else { 05060 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 05061 } 05062 05063 if (!ast_strlen_zero(pagersubject)) { 05064 struct ast_channel *ast; 05065 if ((ast = ast_dummy_channel_alloc())) { 05066 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05067 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 05068 if (check_mime(ast_str_buffer(str1))) { 05069 int first_line = 1; 05070 char *ptr; 05071 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 05072 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 05073 *ptr = '\0'; 05074 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 05075 first_line = 0; 05076 /* Substring is smaller, so this will never grow */ 05077 ast_str_set(&str2, 0, "%s", ptr + 1); 05078 } 05079 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 05080 } else { 05081 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 05082 } 05083 ast = ast_channel_unref(ast); 05084 } else { 05085 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05086 } 05087 } else { 05088 if (ast_strlen_zero(flag)) { 05089 fprintf(p, "Subject: New VM\n\n"); 05090 } else { 05091 fprintf(p, "Subject: New %s VM\n\n", flag); 05092 } 05093 } 05094 05095 if (pagerbody) { 05096 struct ast_channel *ast; 05097 if ((ast = ast_dummy_channel_alloc())) { 05098 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05099 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 05100 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 05101 ast = ast_channel_unref(ast); 05102 } else { 05103 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05104 } 05105 } else { 05106 fprintf(p, "New %s long %s msg in box %s\n" 05107 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 05108 } 05109 05110 fclose(p); 05111 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 05112 ast_safe_system(tmp2); 05113 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 05114 ast_free(str1); 05115 ast_free(str2); 05116 return 0; 05117 }
| static char* show_users_realtime | ( | int | fd, | |
| const char * | context | |||
| ) | [static] |
Definition at line 11261 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().
11262 { 11263 struct ast_config *cfg; 11264 const char *cat = NULL; 11265 11266 if (!(cfg = ast_load_realtime_multientry("voicemail", 11267 "context", context, SENTINEL))) { 11268 return CLI_FAILURE; 11269 } 11270 11271 ast_cli(fd, 11272 "\n" 11273 "=============================================================\n" 11274 "=== Configured Voicemail Users ==============================\n" 11275 "=============================================================\n" 11276 "===\n"); 11277 11278 while ((cat = ast_category_browse(cfg, cat))) { 11279 struct ast_variable *var = NULL; 11280 ast_cli(fd, 11281 "=== Mailbox ...\n" 11282 "===\n"); 11283 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11284 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11285 ast_cli(fd, 11286 "===\n" 11287 "=== ---------------------------------------------------------\n" 11288 "===\n"); 11289 } 11290 11291 ast_cli(fd, 11292 "=============================================================\n" 11293 "\n"); 11294 11295 ast_config_destroy(cfg); 11296 11297 return CLI_SUCCESS; 11298 }
| static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11756 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_pthread_create, mb_poll_thread(), mwi_sub_event_cb(), and mwi_unsub_event_cb().
Referenced by actual_load_config().
11757 { 11758 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11759 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11760 AST_EVENT_IE_END); 11761 11762 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11763 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11764 AST_EVENT_IE_END); 11765 11766 if (mwi_sub_sub) 11767 ast_event_report_subs(mwi_sub_sub); 11768 11769 poll_thread_run = 1; 11770 11771 ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL); 11772 }
| static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11774 of file app_voicemail.c.
References ast_cond_signal, ast_event_unsubscribe(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, and poll_lock.
Referenced by actual_load_config(), and unload_module().
11775 { 11776 poll_thread_run = 0; 11777 11778 if (mwi_sub_sub) { 11779 ast_event_unsubscribe(mwi_sub_sub); 11780 mwi_sub_sub = NULL; 11781 } 11782 11783 if (mwi_unsub_sub) { 11784 ast_event_unsubscribe(mwi_unsub_sub); 11785 mwi_unsub_sub = NULL; 11786 } 11787 11788 ast_mutex_lock(&poll_lock); 11789 ast_cond_signal(&poll_cond); 11790 ast_mutex_unlock(&poll_lock); 11791 11792 pthread_join(poll_thread, NULL); 11793 11794 poll_thread = AST_PTHREADT_NULL; 11795 }
| 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 1058 of file app_voicemail.c.
Referenced by make_email_file(), and sendpage().
01059 { 01060 char *bufptr = buf; 01061 for (; *input; input++) { 01062 if (*input < 32) { 01063 continue; 01064 } 01065 *bufptr++ = *input; 01066 if (bufptr == buf + buflen - 1) { 01067 break; 01068 } 01069 } 01070 *bufptr = '\0'; 01071 return buf; 01072 }
| static const char * substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 11927 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().
11928 { 11929 char *current; 11930 11931 /* Add 16 for fudge factor */ 11932 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11933 11934 ast_str_reset(str); 11935 11936 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11937 for (current = (char *) value; *current; current++) { 11938 if (*current == '\\') { 11939 current++; 11940 if (!*current) { 11941 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11942 break; 11943 } 11944 switch (*current) { 11945 case '\\': 11946 ast_str_append(&str, 0, "\\"); 11947 break; 11948 case 'r': 11949 ast_str_append(&str, 0, "\r"); 11950 break; 11951 case 'n': 11952 #ifdef IMAP_STORAGE 11953 if (!str->used || str->str[str->used - 1] != '\r') { 11954 ast_str_append(&str, 0, "\r"); 11955 } 11956 #endif 11957 ast_str_append(&str, 0, "\n"); 11958 break; 11959 case 't': 11960 ast_str_append(&str, 0, "\t"); 11961 break; 11962 default: 11963 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11964 break; 11965 } 11966 } else { 11967 ast_str_append(&str, 0, "%c", *current); 11968 } 11969 } 11970 11971 return ast_str_buffer(str); 11972 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 13312 of file app_voicemail.c.
References ao2_ref, 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, stop_poll_thread(), and vm_info_acf.
13313 { 13314 int res; 13315 13316 res = ast_unregister_application(app); 13317 res |= ast_unregister_application(app2); 13318 res |= ast_unregister_application(app3); 13319 res |= ast_unregister_application(app4); 13320 res |= ast_unregister_application(sayname_app); 13321 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13322 res |= ast_custom_function_unregister(&vm_info_acf); 13323 res |= ast_manager_unregister("VoicemailUsersList"); 13324 res |= ast_data_unregister(NULL); 13325 #ifdef TEST_FRAMEWORK 13326 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13327 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13328 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13329 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13330 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13331 res |= AST_TEST_UNREGISTER(test_voicemail_vm_info); 13332 #endif 13333 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13334 ast_uninstall_vm_functions(); 13335 ao2_ref(inprocess_container, -1); 13336 13337 if (poll_thread != AST_PTHREADT_NULL) 13338 stop_poll_thread(); 13339 13340 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13341 ast_unload_realtime("voicemail"); 13342 ast_unload_realtime("voicemail_data"); 13343 13344 free_vm_users(); 13345 free_vm_zones(); 13346 return res; 13347 }
| static int vm_allocate_dh | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu, | |||
| int | count_msg | |||
| ) | [static] |
Definition at line 1849 of file app_voicemail.c.
References ast_calloc, ast_realloc, vm_state::deleted, vm_state::dh_arraysize, vm_state::heard, and ast_vm_user::maxmsg.
Referenced by open_mailbox().
01849 { 01850 01851 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01852 if (!vms->dh_arraysize) { 01853 /* initial allocation */ 01854 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01855 return -1; 01856 } 01857 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01858 return -1; 01859 } 01860 vms->dh_arraysize = arraysize; 01861 } else if (vms->dh_arraysize < arraysize) { 01862 if (!(vms->deleted = ast_realloc(vms->deleted, arraysize * sizeof(int)))) { 01863 return -1; 01864 } 01865 if (!(vms->heard = ast_realloc(vms->heard, arraysize * sizeof(int)))) { 01866 return -1; 01867 } 01868 memset(vms->deleted, 0, arraysize * sizeof(int)); 01869 memset(vms->heard, 0, arraysize * sizeof(int)); 01870 vms->dh_arraysize = arraysize; 01871 } 01872 01873 return 0; 01874 }
| 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 9841 of file app_voicemail.c.
References adsi_begin(), adsi_login(), adsi_password(), ast_channel_language(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_test_suite_event_notify, ast_verb, ast_waitstream(), ast_channel::caller, ast_channel::context, find_user(), ast_party_caller::id, ast_party_id::number, ast_vm_user::password, S_COR, ast_party_number::str, ast_party_number::valid, and vm_password.
Referenced by vm_execmain(), and vmauthenticate().
09844 { 09845 int useadsi = 0, valid = 0, logretries = 0; 09846 char password[AST_MAX_EXTENSION]="", *passptr; 09847 struct ast_vm_user vmus, *vmu = NULL; 09848 09849 /* If ADSI is supported, setup login screen */ 09850 adsi_begin(chan, &useadsi); 09851 if (!skipuser && useadsi) 09852 adsi_login(chan); 09853 ast_test_suite_event_notify("PLAYBACK", "Message: vm-login"); 09854 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", ast_channel_language(chan))) { 09855 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09856 return -1; 09857 } 09858 09859 /* Authenticate them and get their mailbox/password */ 09860 09861 while (!valid && (logretries < max_logins)) { 09862 /* Prompt for, and read in the username */ 09863 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09864 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09865 return -1; 09866 } 09867 if (ast_strlen_zero(mailbox)) { 09868 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09869 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09870 } else { 09871 ast_verb(3, "Username not entered\n"); 09872 return -1; 09873 } 09874 } else if (mailbox[0] == '*') { 09875 /* user entered '*' */ 09876 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09877 if (ast_exists_extension(chan, chan->context, "a", 1, 09878 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09879 return -1; 09880 } 09881 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09882 mailbox[0] = '\0'; 09883 } 09884 09885 if (useadsi) 09886 adsi_password(chan); 09887 09888 if (!ast_strlen_zero(prefix)) { 09889 char fullusername[80] = ""; 09890 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09891 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09892 ast_copy_string(mailbox, fullusername, mailbox_size); 09893 } 09894 09895 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09896 vmu = find_user(&vmus, context, mailbox); 09897 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09898 /* saved password is blank, so don't bother asking */ 09899 password[0] = '\0'; 09900 } else { 09901 ast_test_suite_event_notify("PLAYBACK", "Message: %s", vm_password); 09902 if (ast_streamfile(chan, vm_password, ast_channel_language(chan))) { 09903 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09904 return -1; 09905 } 09906 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09907 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09908 return -1; 09909 } else if (password[0] == '*') { 09910 /* user entered '*' */ 09911 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09912 if (ast_exists_extension(chan, chan->context, "a", 1, 09913 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09914 mailbox[0] = '*'; 09915 return -1; 09916 } 09917 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09918 mailbox[0] = '\0'; 09919 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09920 vmu = NULL; 09921 } 09922 } 09923 09924 if (vmu) { 09925 passptr = vmu->password; 09926 if (passptr[0] == '-') passptr++; 09927 } 09928 if (vmu && !strcmp(passptr, password)) 09929 valid++; 09930 else { 09931 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09932 if (!ast_strlen_zero(prefix)) 09933 mailbox[0] = '\0'; 09934 } 09935 logretries++; 09936 if (!valid) { 09937 if (skipuser || logretries >= max_logins) { 09938 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect"); 09939 if (ast_streamfile(chan, "vm-incorrect", ast_channel_language(chan))) { 09940 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09941 return -1; 09942 } 09943 } else { 09944 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect-mailbox"); 09945 if (useadsi) 09946 adsi_login(chan); 09947 if (ast_streamfile(chan, "vm-incorrect-mailbox", ast_channel_language(chan))) { 09948 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09949 return -1; 09950 } 09951 } 09952 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09953 return -1; 09954 } 09955 } 09956 if (!valid && (logretries >= max_logins)) { 09957 ast_stopstream(chan); 09958 ast_play_and_wait(chan, "vm-goodbye"); 09959 return -1; 09960 } 09961 if (vmu && !skipuser) { 09962 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09963 } 09964 return 0; 09965 }
| static int vm_box_exists | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 11071 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().
11072 { 11073 struct ast_vm_user svm; 11074 char *context, *box; 11075 AST_DECLARE_APP_ARGS(args, 11076 AST_APP_ARG(mbox); 11077 AST_APP_ARG(options); 11078 ); 11079 static int dep_warning = 0; 11080 11081 if (ast_strlen_zero(data)) { 11082 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 11083 return -1; 11084 } 11085 11086 if (!dep_warning) { 11087 dep_warning = 1; 11088 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${VM_INFO(%s,exists)} instead.\n", data); 11089 } 11090 11091 box = ast_strdupa(data); 11092 11093 AST_STANDARD_APP_ARGS(args, box); 11094 11095 if (args.options) { 11096 } 11097 11098 if ((context = strchr(args.mbox, '@'))) { 11099 *context = '\0'; 11100 context++; 11101 } 11102 11103 if (find_user(&svm, context, args.mbox)) { 11104 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11105 } else 11106 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11107 11108 return 0; 11109 }
| 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. |
Definition at line 9820 of file app_voicemail.c.
References ast_channel_language(), 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().
09821 { 09822 if (!strncasecmp(ast_channel_language(chan), "es", 2)) { /* SPANISH */ 09823 return vm_browse_messages_es(chan, vms, vmu); 09824 } else if (!strncasecmp(ast_channel_language(chan), "gr", 2)) { /* GREEK */ 09825 return vm_browse_messages_gr(chan, vms, vmu); 09826 } else if (!strncasecmp(ast_channel_language(chan), "he", 2)) { /* HEBREW */ 09827 return vm_browse_messages_he(chan, vms, vmu); 09828 } else if (!strncasecmp(ast_channel_language(chan), "it", 2)) { /* ITALIAN */ 09829 return vm_browse_messages_it(chan, vms, vmu); 09830 } else if (!strncasecmp(ast_channel_language(chan), "pt", 2)) { /* PORTUGUESE */ 09831 return vm_browse_messages_pt(chan, vms, vmu); 09832 } else if (!strncasecmp(ast_channel_language(chan), "vi", 2)) { /* VIETNAMESE */ 09833 return vm_browse_messages_vi(chan, vms, vmu); 09834 } else if (!strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) */ 09835 return vm_browse_messages_zh(chan, vms, vmu); 09836 } else { /* Default to English syntax */ 09837 return vm_browse_messages_en(chan, vms, vmu); 09838 } 09839 }
| 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 9659 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().
09660 { 09661 int cmd = 0; 09662 09663 if (vms->lastmsg > -1) { 09664 cmd = play_message(chan, vmu, vms); 09665 } else { 09666 cmd = ast_play_and_wait(chan, "vm-youhave"); 09667 if (!cmd) 09668 cmd = ast_play_and_wait(chan, "vm-no"); 09669 if (!cmd) { 09670 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09671 cmd = ast_play_and_wait(chan, vms->fn); 09672 } 09673 if (!cmd) 09674 cmd = ast_play_and_wait(chan, "vm-messages"); 09675 } 09676 return cmd; 09677 }
| 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 9713 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().
09714 { 09715 int cmd; 09716 09717 if (vms->lastmsg > -1) { 09718 cmd = play_message(chan, vmu, vms); 09719 } else { 09720 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09721 if (!cmd) 09722 cmd = ast_play_and_wait(chan, "vm-messages"); 09723 if (!cmd) { 09724 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09725 cmd = ast_play_and_wait(chan, vms->fn); 09726 } 09727 } 09728 return cmd; 09729 }
| 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 9607 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().
09608 { 09609 int cmd = 0; 09610 09611 if (vms->lastmsg > -1) { 09612 cmd = play_message(chan, vmu, vms); 09613 } else { 09614 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09615 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09616 if (!cmd) { 09617 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09618 cmd = ast_play_and_wait(chan, vms->fn); 09619 } 09620 if (!cmd) 09621 cmd = ast_play_and_wait(chan, "vm-messages"); 09622 } else { 09623 if (!cmd) 09624 cmd = ast_play_and_wait(chan, "vm-messages"); 09625 if (!cmd) { 09626 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09627 cmd = ast_play_and_wait(chan, vms->fn); 09628 } 09629 } 09630 } 09631 return cmd; 09632 }
| static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| struct ast_vm_user * | vmu | |||
| ) | [static] |
Definition at line 9635 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09636 { 09637 int cmd = 0; 09638 09639 if (vms->lastmsg > -1) { 09640 cmd = play_message(chan, vmu, vms); 09641 } else { 09642 if (!strcasecmp(vms->fn, "INBOX")) { 09643 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09644 } else { 09645 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09646 } 09647 } 09648 return cmd; 09649 }
| 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 9687 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().
09688 { 09689 int cmd; 09690 09691 if (vms->lastmsg > -1) { 09692 cmd = play_message(chan, vmu, vms); 09693 } else { 09694 cmd = ast_play_and_wait(chan, "vm-no"); 09695 if (!cmd) 09696 cmd = ast_play_and_wait(chan, "vm-message"); 09697 if (!cmd) { 09698 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09699 cmd = ast_play_and_wait(chan, vms->fn); 09700 } 09701 } 09702 return cmd; 09703 }
| 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 9739 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().
09740 { 09741 int cmd; 09742 09743 if (vms->lastmsg > -1) { 09744 cmd = play_message(chan, vmu, vms); 09745 } else { 09746 cmd = ast_play_and_wait(chan, "vm-no"); 09747 if (!cmd) { 09748 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09749 cmd = ast_play_and_wait(chan, vms->fn); 09750 } 09751 if (!cmd) 09752 cmd = ast_play_and_wait(chan, "vm-messages"); 09753 } 09754 return cmd; 09755 }
| 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 9793 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().
09794 { 09795 int cmd = 0; 09796 09797 if (vms->lastmsg > -1) { 09798 cmd = play_message(chan, vmu, vms); 09799 } else { 09800 cmd = ast_play_and_wait(chan, "vm-no"); 09801 if (!cmd) { 09802 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09803 cmd = ast_play_and_wait(chan, vms->fn); 09804 } 09805 } 09806 return cmd; 09807 }
| 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 9765 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().
09766 { 09767 int cmd; 09768 09769 if (vms->lastmsg > -1) { 09770 cmd = play_message(chan, vmu, vms); 09771 } else { 09772 cmd = ast_play_and_wait(chan, "vm-you"); 09773 if (!cmd) 09774 cmd = ast_play_and_wait(chan, "vm-haveno"); 09775 if (!cmd) 09776 cmd = ast_play_and_wait(chan, "vm-messages"); 09777 if (!cmd) { 09778 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09779 cmd = ast_play_and_wait(chan, vms->fn); 09780 } 09781 } 09782 return cmd; 09783 }
| 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 1605 of file app_voicemail.c.
References ast_category_browse(), ast_category_get(), 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, CONFIG_STATUS_FILEINVALID, 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(), value, var, VOICEMAIL_CONFIG, and write_password_to_file().
Referenced by vm_newuser(), and vm_options().
01606 { 01607 struct ast_config *cfg = NULL; 01608 struct ast_variable *var = NULL; 01609 struct ast_category *cat = NULL; 01610 char *category = NULL, *value = NULL, *new = NULL; 01611 const char *tmp = NULL; 01612 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01613 char secretfn[PATH_MAX] = ""; 01614 int found = 0; 01615 01616 if (!change_password_realtime(vmu, newpassword)) 01617 return; 01618 01619 /* check if we should store the secret in the spool directory next to the messages */ 01620 switch (vmu->passwordlocation) { 01621 case OPT_PWLOC_SPOOLDIR: 01622 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01623 if (write_password_to_file(secretfn, newpassword) == 0) { 01624 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf"); 01625 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01626 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01627 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01628 break; 01629 } else { 01630 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01631 } 01632 /* Fall-through */ 01633 case OPT_PWLOC_VOICEMAILCONF: 01634 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01635 while ((category = ast_category_browse(cfg, category))) { 01636 if (!strcasecmp(category, vmu->context)) { 01637 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01638 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01639 break; 01640 } 01641 value = strstr(tmp, ","); 01642 if (!value) { 01643 new = alloca(strlen(newpassword)+1); 01644 sprintf(new, "%s", newpassword); 01645 } else { 01646 new = alloca((strlen(value) + strlen(newpassword) + 1)); 01647 sprintf(new, "%s%s", newpassword, value); 01648 } 01649 if (!(cat = ast_category_get(cfg, category))) { 01650 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01651 break; 01652 } 01653 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01654 found = 1; 01655 } 01656 } 01657 /* save the results */ 01658 if (found) { 01659 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf"); 01660 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01661 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01662 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01663 break; 01664 } 01665 } 01666 /* Fall-through */ 01667 case OPT_PWLOC_USERSCONF: 01668 /* check users.conf and update the password stored for the mailbox */ 01669 /* if no vmsecret entry exists create one. */ 01670 if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01671 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01672 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01673 ast_debug(4, "users.conf: %s\n", category); 01674 if (!strcasecmp(category, vmu->mailbox)) { 01675 if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) { 01676 ast_debug(3, "looks like we need to make vmsecret!\n"); 01677 var = ast_variable_new("vmsecret", newpassword, ""); 01678 } else { 01679 var = NULL; 01680 } 01681 new = alloca(strlen(newpassword) + 1); 01682 sprintf(new, "%s", newpassword); 01683 if (!(cat = ast_category_get(cfg, category))) { 01684 ast_debug(4, "failed to get category!\n"); 01685 ast_free(var); 01686 break; 01687 } 01688 if (!var) { 01689 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01690 } else { 01691 ast_variable_append(cat, var); 01692 } 01693 found = 1; 01694 break; 01695 } 01696 } 01697 /* save the results and clean things up */ 01698 if (found) { 01699 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf"); 01700 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01701 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01702 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01703 } 01704 } 01705 } 01706 }
| static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
| char * | newpassword | |||
| ) | [static] |
Definition at line 1708 of file app_voicemail.c.
References ast_copy_string(), ast_debug, ast_safe_system(), ast_test_suite_event_notify, ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().
Referenced by vm_newuser(), and vm_options().
01709 { 01710 char buf[255]; 01711 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01712 ast_debug(1, "External password: %s\n",buf); 01713 if (!ast_safe_system(buf)) { 01714 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external"); 01715 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01716 /* Reset the password in memory, too */ 01717 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01718 } 01719 }
| static char* vm_check_password_shell | ( | char * | command, | |
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 1270 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().
01271 { 01272 int fds[2], pid = 0; 01273 01274 memset(buf, 0, len); 01275 01276 if (pipe(fds)) { 01277 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 01278 } else { 01279 /* good to go*/ 01280 pid = ast_safe_fork(0); 01281 01282 if (pid < 0) { 01283 /* ok maybe not */ 01284 close(fds[0]); 01285 close(fds[1]); 01286 snprintf(buf, len, "FAILURE: Fork failed"); 01287 } else if (pid) { 01288 /* parent */ 01289 close(fds[1]); 01290 if (read(fds[0], buf, len) < 0) { 01291 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 01292 } 01293 close(fds[0]); 01294 } else { 01295 /* child */ 01296 AST_DECLARE_APP_ARGS(arg, 01297 AST_APP_ARG(v)[20]; 01298 ); 01299 char *mycmd = ast_strdupa(command); 01300 01301 close(fds[0]); 01302 dup2(fds[1], STDOUT_FILENO); 01303 close(fds[1]); 01304 ast_close_fds_above_n(STDOUT_FILENO); 01305 01306 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 01307 01308 execv(arg.v[0], arg.v); 01309 printf("FAILURE: %s", strerror(errno)); 01310 _exit(0); 01311 } 01312 } 01313 return buf; 01314 }
| 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. |
Definition at line 4279 of file app_voicemail.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
04280 { 04281 char *txt; 04282 int txtsize = 0; 04283 04284 txtsize = (strlen(file) + 5)*sizeof(char); 04285 txt = alloca(txtsize); 04286 /* Sprintf here would safe because we alloca'd exactly the right length, 04287 * but trying to eliminate all sprintf's anyhow 04288 */ 04289 if (ast_check_realtime("voicemail_data")) { 04290 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04291 } 04292 snprintf(txt, txtsize, "%s.txt", file); 04293 unlink(txt); 04294 return ast_filedelete(file, NULL); 04295 }
| static int vm_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 10718 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(), leave_vm_options::record_gain, and vm_app_options.
Referenced by load_module(), and play_record_review().
10719 { 10720 int res = 0; 10721 char *tmp; 10722 struct leave_vm_options leave_options; 10723 struct ast_flags flags = { 0 }; 10724 char *opts[OPT_ARG_ARRAY_SIZE]; 10725 AST_DECLARE_APP_ARGS(args, 10726 AST_APP_ARG(argv0); 10727 AST_APP_ARG(argv1); 10728 ); 10729 10730 memset(&leave_options, 0, sizeof(leave_options)); 10731 10732 if (chan->_state != AST_STATE_UP) 10733 ast_answer(chan); 10734 10735 if (!ast_strlen_zero(data)) { 10736 tmp = ast_strdupa(data); 10737 AST_STANDARD_APP_ARGS(args, tmp); 10738 if (args.argc == 2) { 10739 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10740 return -1; 10741 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10742 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10743 int gain; 10744 10745 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10746 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10747 return -1; 10748 } else { 10749 leave_options.record_gain = (signed char) gain; 10750 } 10751 } 10752 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10753 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10754 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10755 } 10756 } 10757 } else { 10758 char temp[256]; 10759 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10760 if (res < 0) 10761 return res; 10762 if (ast_strlen_zero(temp)) 10763 return 0; 10764 args.argv0 = ast_strdupa(temp); 10765 } 10766 10767 res = leave_voicemail(chan, args.argv0, &leave_options); 10768 if (res == 't') { 10769 ast_play_and_wait(chan, "vm-goodbye"); 10770 res = 0; 10771 } 10772 10773 if (res == OPERATOR_EXIT) { 10774 res = 0; 10775 } 10776 10777 if (res == ERROR_LOCK_PATH) { 10778 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10779 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10780 res = 0; 10781 } 10782 10783 return res; 10784 }
| static int vm_execmain | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 9967 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_channel_language(), 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_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, ast_vm_user::language, vm_state::lastmsg, ast_vm_user::mailbox, make_file(), 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_app_options, 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, and vm_state::vmbox.
Referenced by load_module().
09968 { 09969 /* XXX This is, admittedly, some pretty horrendous code. For some 09970 reason it just seemed a lot easier to do with GOTO's. I feel 09971 like I'm back in my GWBASIC days. XXX */ 09972 int res = -1; 09973 int cmd = 0; 09974 int valid = 0; 09975 char prefixstr[80] =""; 09976 char ext_context[256]=""; 09977 int box; 09978 int useadsi = 0; 09979 int skipuser = 0; 09980 struct vm_state vms; 09981 struct ast_vm_user *vmu = NULL, vmus; 09982 char *context = NULL; 09983 int silentexit = 0; 09984 struct ast_flags flags = { 0 }; 09985 signed char record_gain = 0; 09986 int play_auto = 0; 09987 int play_folder = 0; 09988 int in_urgent = 0; 09989 #ifdef IMAP_STORAGE 09990 int deleted = 0; 09991 #endif 09992 09993 /* Add the vm_state to the active list and keep it active */ 09994 memset(&vms, 0, sizeof(vms)); 09995 09996 vms.lastmsg = -1; 09997 09998 memset(&vmus, 0, sizeof(vmus)); 09999 10000 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 10001 if (chan->_state != AST_STATE_UP) { 10002 ast_debug(1, "Before ast_answer\n"); 10003 ast_answer(chan); 10004 } 10005 10006 if (!ast_strlen_zero(data)) { 10007 char *opts[OPT_ARG_ARRAY_SIZE]; 10008 char *parse; 10009 AST_DECLARE_APP_ARGS(args, 10010 AST_APP_ARG(argv0); 10011 AST_APP_ARG(argv1); 10012 ); 10013 10014 parse = ast_strdupa(data); 10015 10016 AST_STANDARD_APP_ARGS(args, parse); 10017 10018 if (args.argc == 2) { 10019 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10020 return -1; 10021 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10022 int gain; 10023 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 10024 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10025 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10026 return -1; 10027 } else { 10028 record_gain = (signed char) gain; 10029 } 10030 } else { 10031 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 10032 } 10033 } 10034 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 10035 play_auto = 1; 10036 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 10037 /* See if it is a folder name first */ 10038 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 10039 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 10040 play_folder = -1; 10041 } 10042 } else { 10043 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 10044 } 10045 } else { 10046 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 10047 } 10048 if (play_folder > 9 || play_folder < 0) { 10049 ast_log(AST_LOG_WARNING, 10050 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 10051 opts[OPT_ARG_PLAYFOLDER]); 10052 play_folder = 0; 10053 } 10054 } 10055 } else { 10056 /* old style options parsing */ 10057 while (*(args.argv0)) { 10058 if (*(args.argv0) == 's') 10059 ast_set_flag(&flags, OPT_SILENT); 10060 else if (*(args.argv0) == 'p') 10061 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 10062 else 10063 break; 10064 (args.argv0)++; 10065 } 10066 10067 } 10068 10069 valid = ast_test_flag(&flags, OPT_SILENT); 10070 10071 if ((context = strchr(args.argv0, '@'))) 10072 *context++ = '\0'; 10073 10074 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 10075 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 10076 else 10077 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 10078 10079 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 10080 skipuser++; 10081 else 10082 valid = 0; 10083 } 10084 10085 if (!valid) 10086 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 10087 10088 ast_debug(1, "After vm_authenticate\n"); 10089 10090 if (vms.username[0] == '*') { 10091 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 10092 10093 /* user entered '*' */ 10094 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10095 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 10096 res = 0; /* prevent hangup */ 10097 goto out; 10098 } 10099 } 10100 10101 if (!res) { 10102 valid = 1; 10103 if (!skipuser) 10104 vmu = &vmus; 10105 } else { 10106 res = 0; 10107 } 10108 10109 /* If ADSI is supported, setup login screen */ 10110 adsi_begin(chan, &useadsi); 10111 10112 ast_test_suite_assert(valid); 10113 if (!valid) { 10114 goto out; 10115 } 10116 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10117 10118 #ifdef IMAP_STORAGE 10119 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10120 pthread_setspecific(ts_vmstate.key, &vms); 10121 10122 vms.interactive = 1; 10123 vms.updated = 1; 10124 if (vmu) 10125 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10126 vmstate_insert(&vms); 10127 init_vm_state(&vms); 10128 #endif 10129 10130 /* Set language from config to override channel language */ 10131 if (!ast_strlen_zero(vmu->language)) 10132 ast_channel_language_set(chan, vmu->language); 10133 10134 /* Retrieve urgent, old and new message counts */ 10135 ast_debug(1, "Before open_mailbox\n"); 10136 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10137 if (res < 0) 10138 goto out; 10139 vms.oldmessages = vms.lastmsg + 1; 10140 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10141 /* check INBOX */ 10142 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10143 if (res < 0) 10144 goto out; 10145 vms.newmessages = vms.lastmsg + 1; 10146 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10147 /* Start in Urgent */ 10148 in_urgent = 1; 10149 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10150 if (res < 0) 10151 goto out; 10152 vms.urgentmessages = vms.lastmsg + 1; 10153 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10154 10155 /* Select proper mailbox FIRST!! */ 10156 if (play_auto) { 10157 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10158 if (vms.urgentmessages) { 10159 in_urgent = 1; 10160 res = open_mailbox(&vms, vmu, 11); 10161 } else { 10162 in_urgent = 0; 10163 res = open_mailbox(&vms, vmu, play_folder); 10164 } 10165 if (res < 0) 10166 goto out; 10167 10168 /* If there are no new messages, inform the user and hangup */ 10169 if (vms.lastmsg == -1) { 10170 in_urgent = 0; 10171 cmd = vm_browse_messages(chan, &vms, vmu); 10172 res = 0; 10173 goto out; 10174 } 10175 } else { 10176 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10177 /* If we only have old messages start here */ 10178 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10179 in_urgent = 0; 10180 play_folder = 1; 10181 if (res < 0) 10182 goto out; 10183 } else if (!vms.urgentmessages && vms.newmessages) { 10184 /* If we have new messages but none are urgent */ 10185 in_urgent = 0; 10186 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10187 if (res < 0) 10188 goto out; 10189 } 10190 } 10191 10192 if (useadsi) 10193 adsi_status(chan, &vms); 10194 res = 0; 10195 10196 /* Check to see if this is a new user */ 10197 if (!strcasecmp(vmu->mailbox, vmu->password) && 10198 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10199 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10200 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10201 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10202 if ((cmd == 't') || (cmd == '#')) { 10203 /* Timeout */ 10204 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10205 res = 0; 10206 goto out; 10207 } else if (cmd < 0) { 10208 /* Hangup */ 10209 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10210 res = -1; 10211 goto out; 10212 } 10213 } 10214 #ifdef IMAP_STORAGE 10215 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10216 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10217 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10218 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10219 } 10220 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10221 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10222 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10223 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10224 } 10225 #endif 10226 10227 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10228 if (play_auto) { 10229 cmd = '1'; 10230 } else { 10231 cmd = vm_intro(chan, vmu, &vms); 10232 } 10233 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10234 10235 vms.repeats = 0; 10236 vms.starting = 1; 10237 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10238 /* Run main menu */ 10239 switch (cmd) { 10240 case '1': /* First message */ 10241 vms.curmsg = 0; 10242 /* Fall through */ 10243 case '5': /* Play current message */ 10244 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10245 cmd = vm_browse_messages(chan, &vms, vmu); 10246 break; 10247 case '2': /* Change folders */ 10248 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10249 if (useadsi) 10250 adsi_folders(chan, 0, "Change to folder..."); 10251 10252 cmd = get_folder2(chan, "vm-changeto", 0); 10253 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10254 if (cmd == '#') { 10255 cmd = 0; 10256 } else if (cmd > 0) { 10257 cmd = cmd - '0'; 10258 res = close_mailbox(&vms, vmu); 10259 if (res == ERROR_LOCK_PATH) 10260 goto out; 10261 /* If folder is not urgent, set in_urgent to zero! */ 10262 if (cmd != 11) in_urgent = 0; 10263 res = open_mailbox(&vms, vmu, cmd); 10264 if (res < 0) 10265 goto out; 10266 play_folder = cmd; 10267 cmd = 0; 10268 } 10269 if (useadsi) 10270 adsi_status2(chan, &vms); 10271 10272 if (!cmd) { 10273 cmd = vm_play_folder_name(chan, vms.vmbox); 10274 } 10275 10276 vms.starting = 1; 10277 break; 10278 case '3': /* Advanced options */ 10279 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10280 cmd = 0; 10281 vms.repeats = 0; 10282 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10283 switch (cmd) { 10284 case '1': /* Reply */ 10285 if (vms.lastmsg > -1 && !vms.starting) { 10286 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10287 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10288 res = cmd; 10289 goto out; 10290 } 10291 } else { 10292 cmd = ast_play_and_wait(chan, "vm-sorry"); 10293 } 10294 cmd = 't'; 10295 break; 10296 case '2': /* Callback */ 10297 if (!vms.starting) 10298 ast_verb(3, "Callback Requested\n"); 10299 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10300 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10301 if (cmd == 9) { 10302 silentexit = 1; 10303 goto out; 10304 } else if (cmd == ERROR_LOCK_PATH) { 10305 res = cmd; 10306 goto out; 10307 } 10308 } else { 10309 cmd = ast_play_and_wait(chan, "vm-sorry"); 10310 } 10311 cmd = 't'; 10312 break; 10313 case '3': /* Envelope */ 10314 if (vms.lastmsg > -1 && !vms.starting) { 10315 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10316 if (cmd == ERROR_LOCK_PATH) { 10317 res = cmd; 10318 goto out; 10319 } 10320 } else { 10321 cmd = ast_play_and_wait(chan, "vm-sorry"); 10322 } 10323 cmd = 't'; 10324 break; 10325 case '4': /* Dialout */ 10326 if (!ast_strlen_zero(vmu->dialout)) { 10327 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10328 if (cmd == 9) { 10329 silentexit = 1; 10330 goto out; 10331 } 10332 } else { 10333 cmd = ast_play_and_wait(chan, "vm-sorry"); 10334 } 10335 cmd = 't'; 10336 break; 10337 10338 case '5': /* Leave VoiceMail */ 10339 if (ast_test_flag(vmu, VM_SVMAIL)) { 10340 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10341 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10342 res = cmd; 10343 goto out; 10344 } 10345 } else { 10346 cmd = ast_play_and_wait(chan, "vm-sorry"); 10347 } 10348 cmd = 't'; 10349 break; 10350 10351 case '*': /* Return to main menu */ 10352 cmd = 't'; 10353 break; 10354 10355 default: 10356 cmd = 0; 10357 if (!vms.starting) { 10358 cmd = ast_play_and_wait(chan, "vm-toreply"); 10359 } 10360 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10361 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10362 } 10363 if (!cmd && !vms.starting) { 10364 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10365 } 10366 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10367 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10368 } 10369 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10370 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10371 } 10372 if (!cmd) { 10373 cmd = ast_play_and_wait(chan, "vm-starmain"); 10374 } 10375 if (!cmd) { 10376 cmd = ast_waitfordigit(chan, 6000); 10377 } 10378 if (!cmd) { 10379 vms.repeats++; 10380 } 10381 if (vms.repeats > 3) { 10382 cmd = 't'; 10383 } 10384 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10385 } 10386 } 10387 if (cmd == 't') { 10388 cmd = 0; 10389 vms.repeats = 0; 10390 } 10391 break; 10392 case '4': /* Go to the previous message */ 10393 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10394 if (vms.curmsg > 0) { 10395 vms.curmsg--; 10396 cmd = play_message(chan, vmu, &vms); 10397 } else { 10398 /* Check if we were listening to new 10399 messages. If so, go to Urgent messages 10400 instead of saying "no more messages" 10401 */ 10402 if (in_urgent == 0 && vms.urgentmessages > 0) { 10403 /* Check for Urgent messages */ 10404 in_urgent = 1; 10405 res = close_mailbox(&vms, vmu); 10406 if (res == ERROR_LOCK_PATH) 10407 goto out; 10408 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10409 if (res < 0) 10410 goto out; 10411 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10412 vms.curmsg = vms.lastmsg; 10413 if (vms.lastmsg < 0) { 10414 cmd = ast_play_and_wait(chan, "vm-nomore"); 10415 } 10416 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10417 vms.curmsg = vms.lastmsg; 10418 cmd = play_message(chan, vmu, &vms); 10419 } else { 10420 cmd = ast_play_and_wait(chan, "vm-nomore"); 10421 } 10422 } 10423 break; 10424 case '6': /* Go to the next message */ 10425 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10426 if (vms.curmsg < vms.lastmsg) { 10427 vms.curmsg++; 10428 cmd = play_message(chan, vmu, &vms); 10429 } else { 10430 if (in_urgent && vms.newmessages > 0) { 10431 /* Check if we were listening to urgent 10432 * messages. If so, go to regular new messages 10433 * instead of saying "no more messages" 10434 */ 10435 in_urgent = 0; 10436 res = close_mailbox(&vms, vmu); 10437 if (res == ERROR_LOCK_PATH) 10438 goto out; 10439 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10440 if (res < 0) 10441 goto out; 10442 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10443 vms.curmsg = -1; 10444 if (vms.lastmsg < 0) { 10445 cmd = ast_play_and_wait(chan, "vm-nomore"); 10446 } 10447 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10448 vms.curmsg = 0; 10449 cmd = play_message(chan, vmu, &vms); 10450 } else { 10451 cmd = ast_play_and_wait(chan, "vm-nomore"); 10452 } 10453 } 10454 break; 10455 case '7': /* Delete the current message */ 10456 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10457 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10458 if (useadsi) 10459 adsi_delete(chan, &vms); 10460 if (vms.deleted[vms.curmsg]) { 10461 if (play_folder == 0) { 10462 if (in_urgent) { 10463 vms.urgentmessages--; 10464 } else { 10465 vms.newmessages--; 10466 } 10467 } 10468 else if (play_folder == 1) 10469 vms.oldmessages--; 10470 cmd = ast_play_and_wait(chan, "vm-deleted"); 10471 } else { 10472 if (play_folder == 0) { 10473 if (in_urgent) { 10474 vms.urgentmessages++; 10475 } else { 10476 vms.newmessages++; 10477 } 10478 } 10479 else if (play_folder == 1) 10480 vms.oldmessages++; 10481 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10482 } 10483 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10484 if (vms.curmsg < vms.lastmsg) { 10485 vms.curmsg++; 10486 cmd = play_message(chan, vmu, &vms); 10487 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10488 vms.curmsg = 0; 10489 cmd = play_message(chan, vmu, &vms); 10490 } else { 10491 /* Check if we were listening to urgent 10492 messages. If so, go to regular new messages 10493 instead of saying "no more messages" 10494 */ 10495 if (in_urgent == 1) { 10496 /* Check for new messages */ 10497 in_urgent = 0; 10498 res = close_mailbox(&vms, vmu); 10499 if (res == ERROR_LOCK_PATH) 10500 goto out; 10501 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10502 if (res < 0) 10503 goto out; 10504 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10505 vms.curmsg = -1; 10506 if (vms.lastmsg < 0) { 10507 cmd = ast_play_and_wait(chan, "vm-nomore"); 10508 } 10509 } else { 10510 cmd = ast_play_and_wait(chan, "vm-nomore"); 10511 } 10512 } 10513 } 10514 } else /* Delete not valid if we haven't selected a message */ 10515 cmd = 0; 10516 #ifdef IMAP_STORAGE 10517 deleted = 1; 10518 #endif 10519 break; 10520 10521 case '8': /* Forward the current message */ 10522 if (vms.lastmsg > -1) { 10523 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10524 if (cmd == ERROR_LOCK_PATH) { 10525 res = cmd; 10526 goto out; 10527 } 10528 } else { 10529 /* Check if we were listening to urgent 10530 messages. If so, go to regular new messages 10531 instead of saying "no more messages" 10532 */ 10533 if (in_urgent == 1 && vms.newmessages > 0) { 10534 /* Check for new messages */ 10535 in_urgent = 0; 10536 res = close_mailbox(&vms, vmu); 10537 if (res == ERROR_LOCK_PATH) 10538 goto out; 10539 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10540 if (res < 0) 10541 goto out; 10542 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10543 vms.curmsg = -1; 10544 if (vms.lastmsg < 0) { 10545 cmd = ast_play_and_wait(chan, "vm-nomore"); 10546 } 10547 } else { 10548 cmd = ast_play_and_wait(chan, "vm-nomore"); 10549 } 10550 } 10551 break; 10552 case '9': /* Save message to folder */ 10553 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10554 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10555 /* No message selected */ 10556 cmd = 0; 10557 break; 10558 } 10559 if (useadsi) 10560 adsi_folders(chan, 1, "Save to folder..."); 10561 cmd = get_folder2(chan, "vm-savefolder", 1); 10562 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10563 box = 0; /* Shut up compiler */ 10564 if (cmd == '#') { 10565 cmd = 0; 10566 break; 10567 } else if (cmd > 0) { 10568 box = cmd = cmd - '0'; 10569 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10570 if (cmd == ERROR_LOCK_PATH) { 10571 res = cmd; 10572 goto out; 10573 #ifndef IMAP_STORAGE 10574 } else if (!cmd) { 10575 vms.deleted[vms.curmsg] = 1; 10576 #endif 10577 } else { 10578 vms.deleted[vms.curmsg] = 0; 10579 vms.heard[vms.curmsg] = 0; 10580 } 10581 } 10582 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10583 if (useadsi) 10584 adsi_message(chan, &vms); 10585 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10586 if (!cmd) { 10587 cmd = ast_play_and_wait(chan, "vm-message"); 10588 if (!cmd) 10589 cmd = say_and_wait(chan, vms.curmsg + 1, ast_channel_language(chan)); 10590 if (!cmd) 10591 cmd = ast_play_and_wait(chan, "vm-savedto"); 10592 if (!cmd) 10593 cmd = vm_play_folder_name(chan, vms.fn); 10594 } else { 10595 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10596 } 10597 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10598 if (vms.curmsg < vms.lastmsg) { 10599 vms.curmsg++; 10600 cmd = play_message(chan, vmu, &vms); 10601 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10602 vms.curmsg = 0; 10603 cmd = play_message(chan, vmu, &vms); 10604 } else { 10605 /* Check if we were listening to urgent 10606 messages. If so, go to regular new messages 10607 instead of saying "no more messages" 10608 */ 10609 if (in_urgent == 1 && vms.newmessages > 0) { 10610 /* Check for new messages */ 10611 in_urgent = 0; 10612 res = close_mailbox(&vms, vmu); 10613 if (res == ERROR_LOCK_PATH) 10614 goto out; 10615 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10616 if (res < 0) 10617 goto out; 10618 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10619 vms.curmsg = -1; 10620 if (vms.lastmsg < 0) { 10621 cmd = ast_play_and_wait(chan, "vm-nomore"); 10622 } 10623 } else { 10624 cmd = ast_play_and_wait(chan, "vm-nomore"); 10625 } 10626 } 10627 } 10628 break; 10629 case '*': /* Help */ 10630 if (!vms.starting) { 10631 cmd = ast_play_and_wait(chan, "vm-onefor"); 10632 if (!strncasecmp(ast_channel_language(chan), "he", 2)) { 10633 cmd = ast_play_and_wait(chan, "vm-for"); 10634 } 10635 if (!cmd) 10636 cmd = vm_play_folder_name(chan, vms.vmbox); 10637 if (!cmd) 10638 cmd = ast_play_and_wait(chan, "vm-opts"); 10639 if (!cmd) 10640 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10641 } else 10642 cmd = 0; 10643 break; 10644 case '0': /* Mailbox options */ 10645 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10646 if (useadsi) 10647 adsi_status(chan, &vms); 10648 break; 10649 default: /* Nothing */ 10650 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10651 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10652 break; 10653 } 10654 } 10655 if ((cmd == 't') || (cmd == '#')) { 10656 /* Timeout */ 10657 res = 0; 10658 } else { 10659 /* Hangup */ 10660 res = -1; 10661 } 10662 10663 out: 10664 if (res > -1) { 10665 ast_stopstream(chan); 10666 adsi_goodbye(chan); 10667 if (valid && res != OPERATOR_EXIT) { 10668 if (silentexit) 10669 res = ast_play_and_wait(chan, "vm-dialout"); 10670 else 10671 res = ast_play_and_wait(chan, "vm-goodbye"); 10672 } 10673 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10674 res = 0; 10675 } 10676 if (useadsi) 10677 ast_adsi_unload_session(chan); 10678 } 10679 if (vmu) 10680 close_mailbox(&vms, vmu); 10681 if (valid) { 10682 int new = 0, old = 0, urgent = 0; 10683 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10684 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10685 /* Urgent flag not passwd to externnotify here */ 10686 run_externnotify(vmu->context, vmu->mailbox, NULL); 10687 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10688 queue_mwi_event(ext_context, urgent, new, old); 10689 } 10690 #ifdef IMAP_STORAGE 10691 /* expunge message - use UID Expunge if supported on IMAP server*/ 10692 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10693 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10694 ast_mutex_lock(&vms.lock); 10695 #ifdef HAVE_IMAP_TK2006 10696 if (LEVELUIDPLUS (vms.mailstream)) { 10697 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10698 } else 10699 #endif 10700 mail_expunge(vms.mailstream); 10701 ast_mutex_unlock(&vms.lock); 10702 } 10703 /* before we delete the state, we should copy pertinent info 10704 * back to the persistent model */ 10705 if (vmu) { 10706 vmstate_delete(&vms); 10707 } 10708 #endif 10709 if (vmu) 10710 free_user(vmu); 10711 10712 #ifdef IMAP_STORAGE 10713 pthread_setspecific(ts_vmstate.key, NULL); 10714 #endif 10715 return res; 10716 }
| 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 |
This is invoked from forward_message() when performing a forward operation (option 8 from main menu).
Definition at line 6943 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, CONFIG_STATUS_FILEINVALID, copy(), INTRO, make_file(), ast_vm_user::maxsecs, play_record_review(), vm_pls_try_again, and vm_prepend_timeout.
Referenced by forward_message().
06945 { 06946 int cmd = 0; 06947 int retries = 0, prepend_duration = 0, already_recorded = 0; 06948 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06949 char textfile[PATH_MAX]; 06950 struct ast_config *msg_cfg; 06951 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06952 #ifndef IMAP_STORAGE 06953 signed char zero_gain = 0; 06954 #endif 06955 const char *duration_str; 06956 06957 /* Must always populate duration correctly */ 06958 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06959 strcpy(textfile, msgfile); 06960 strcpy(backup, msgfile); 06961 strcpy(backup_textfile, msgfile); 06962 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06963 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06964 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06965 06966 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06967 *duration = atoi(duration_str); 06968 } else { 06969 *duration = 0; 06970 } 06971 06972 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06973 if (cmd) 06974 retries = 0; 06975 switch (cmd) { 06976 case '1': 06977 06978 #ifdef IMAP_STORAGE 06979 /* Record new intro file */ 06980 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06981 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06982 ast_play_and_wait(chan, INTRO); 06983 ast_play_and_wait(chan, "beep"); 06984 play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06985 cmd = 't'; 06986 #else 06987 06988 /* prepend a message to the current message, update the metadata and return */ 06989 06990 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06991 strcpy(textfile, msgfile); 06992 strncat(textfile, ".txt", sizeof(textfile) - 1); 06993 *duration = 0; 06994 06995 /* if we can't read the message metadata, stop now */ 06996 if (!msg_cfg) { 06997 cmd = 0; 06998 break; 06999 } 07000 07001 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 07002 #ifndef IMAP_STORAGE 07003 if (already_recorded) { 07004 ast_filecopy(backup, msgfile, NULL); 07005 copy(backup_textfile, textfile); 07006 } 07007 else { 07008 ast_filecopy(msgfile, backup, NULL); 07009 copy(textfile, backup_textfile); 07010 } 07011 #endif 07012 already_recorded = 1; 07013 07014 if (record_gain) 07015 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 07016 07017 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 07018 07019 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 07020 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 07021 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 07022 ast_filerename(backup, msgfile, NULL); 07023 } 07024 07025 if (record_gain) 07026 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 07027 07028 07029 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 07030 *duration = atoi(duration_str); 07031 07032 if (prepend_duration) { 07033 struct ast_category *msg_cat; 07034 /* need enough space for a maximum-length message duration */ 07035 char duration_buf[12]; 07036 07037 *duration += prepend_duration; 07038 msg_cat = ast_category_get(msg_cfg, "message"); 07039 snprintf(duration_buf, 11, "%ld", *duration); 07040 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 07041 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 07042 } 07043 } 07044 07045 #endif 07046 break; 07047 case '2': 07048 /* NULL out introfile so we know there is no intro! */ 07049 #ifdef IMAP_STORAGE 07050 *vms->introfn = '\0'; 07051 #endif 07052 cmd = 't'; 07053 break; 07054 case '*': 07055 cmd = '*'; 07056 break; 07057 default: 07058 /* If time_out and return to menu, reset already_recorded */ 07059 already_recorded = 0; 07060 07061 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 07062 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 07063 if (!cmd) { 07064 cmd = ast_play_and_wait(chan, "vm-starmain"); 07065 /* "press star to return to the main menu" */ 07066 } 07067 if (!cmd) { 07068 cmd = ast_waitfordigit(chan, 6000); 07069 } 07070 if (!cmd) { 07071 retries++; 07072 } 07073 if (retries > 3) { 07074 cmd = '*'; /* Let's cancel this beast */ 07075 } 07076 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07077 } 07078 } 07079 07080 if (msg_cfg) 07081 ast_config_destroy(msg_cfg); 07082 if (prepend_duration) 07083 *duration = prepend_duration; 07084 07085 if (already_recorded && cmd == -1) { 07086 /* restore original message if prepention cancelled */ 07087 ast_filerename(backup, msgfile, NULL); 07088 rename(backup_textfile, textfile); 07089 } 07090 07091 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 07092 cmd = 0; 07093 return cmd; 07094 }
| 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 9285 of file app_voicemail.c.
References ast_channel_language(), vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
09286 { 09287 if (vms->starting && !strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09288 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09289 } else { /* Default to ENGLISH */ 09290 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09291 } 09292 }
| 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 9184 of file app_voicemail.c.
References 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().
09185 { 09186 int res = 0; 09187 /* Play instructions and wait for new command */ 09188 while (!res) { 09189 if (vms->starting) { 09190 if (vms->lastmsg > -1) { 09191 if (skipadvanced) 09192 res = ast_play_and_wait(chan, "vm-onefor-full"); 09193 else 09194 res = ast_play_and_wait(chan, "vm-onefor"); 09195 if (!res) 09196 res = vm_play_folder_name(chan, vms->vmbox); 09197 } 09198 if (!res) { 09199 if (skipadvanced) 09200 res = ast_play_and_wait(chan, "vm-opts-full"); 09201 else 09202 res = ast_play_and_wait(chan, "vm-opts"); 09203 } 09204 } else { 09205 /* Added for additional help */ 09206 if (skipadvanced) { 09207 res = ast_play_and_wait(chan, "vm-onefor-full"); 09208 if (!res) 09209 res = vm_play_folder_name(chan, vms->vmbox); 09210 res = ast_play_and_wait(chan, "vm-opts-full"); 09211 } 09212 /* Logic: 09213 * If the current message is not the first OR 09214 * if we're listening to the first new message and there are 09215 * also urgent messages, then prompt for navigation to the 09216 * previous message 09217 */ 09218 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09219 res = ast_play_and_wait(chan, "vm-prev"); 09220 } 09221 if (!res && !skipadvanced) 09222 res = ast_play_and_wait(chan, "vm-advopts"); 09223 if (!res) 09224 res = ast_play_and_wait(chan, "vm-repeat"); 09225 /* Logic: 09226 * If we're not listening to the last message OR 09227 * we're listening to the last urgent message and there are 09228 * also new non-urgent messages, then prompt for navigation 09229 * to the next message 09230 */ 09231 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09232 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09233 res = ast_play_and_wait(chan, "vm-next"); 09234 } 09235 if (!res) { 09236 if (!vms->deleted[vms->curmsg]) 09237 res = ast_play_and_wait(chan, "vm-delete"); 09238 else 09239 res = ast_play_and_wait(chan, "vm-undelete"); 09240 if (!res) 09241 res = ast_play_and_wait(chan, "vm-toforward"); 09242 if (!res) 09243 res = ast_play_and_wait(chan, "vm-savemessage"); 09244 } 09245 } 09246 if (!res) { 09247 res = ast_play_and_wait(chan, "vm-helpexit"); 09248 } 09249 if (!res) 09250 res = ast_waitfordigit(chan, 6000); 09251 if (!res) { 09252 vms->repeats++; 09253 if (vms->repeats > 2) { 09254 res = 't'; 09255 } 09256 } 09257 } 09258 return res; 09259 }
| 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 9261 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().
09262 { 09263 int res = 0; 09264 /* Play instructions and wait for new command */ 09265 while (!res) { 09266 if (vms->lastmsg > -1) { 09267 res = ast_play_and_wait(chan, "vm-listen"); 09268 if (!res) 09269 res = vm_play_folder_name(chan, vms->vmbox); 09270 if (!res) 09271 res = ast_play_and_wait(chan, "press"); 09272 if (!res) 09273 res = ast_play_and_wait(chan, "digits/1"); 09274 } 09275 if (!res) 09276 res = ast_play_and_wait(chan, "vm-opts"); 09277 if (!res) { 09278 vms->starting = 0; 09279 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09280 } 09281 } 09282 return res; 09283 }
| static int vm_intro | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 9122 of file app_voicemail.c.
References ast_channel_language(), 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(), and VM_TEMPGREETWARN.
Referenced by vm_execmain().
09123 { 09124 char prefile[256]; 09125 09126 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09127 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09128 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09129 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09130 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09131 ast_play_and_wait(chan, "vm-tempgreetactive"); 09132 } 09133 DISPOSE(prefile, -1); 09134 } 09135 09136 /* Play voicemail intro - syntax is different for different languages */ 09137 if (0) { 09138 return 0; 09139 } else if (!strncasecmp(ast_channel_language(chan), "cs", 2)) { /* CZECH syntax */ 09140 return vm_intro_cs(chan, vms); 09141 } else if (!strncasecmp(ast_channel_language(chan), "cz", 2)) { /* deprecated CZECH syntax */ 09142 static int deprecation_warning = 0; 09143 if (deprecation_warning++ % 10 == 0) { 09144 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09145 } 09146 return vm_intro_cs(chan, vms); 09147 } else if (!strncasecmp(ast_channel_language(chan), "de", 2)) { /* GERMAN syntax */ 09148 return vm_intro_de(chan, vms); 09149 } else if (!strncasecmp(ast_channel_language(chan), "es", 2)) { /* SPANISH syntax */ 09150 return vm_intro_es(chan, vms); 09151 } else if (!strncasecmp(ast_channel_language(chan), "fr", 2)) { /* FRENCH syntax */ 09152 return vm_intro_fr(chan, vms); 09153 } else if (!strncasecmp(ast_channel_language(chan), "gr", 2)) { /* GREEK syntax */ 09154 return vm_intro_gr(chan, vms); 09155 } else if (!strncasecmp(ast_channel_language(chan), "he", 2)) { /* HEBREW syntax */ 09156 return vm_intro_he(chan, vms); 09157 } else if (!strncasecmp(ast_channel_language(chan), "it", 2)) { /* ITALIAN syntax */ 09158 return vm_intro_it(chan, vms); 09159 } else if (!strncasecmp(ast_channel_language(chan), "nl", 2)) { /* DUTCH syntax */ 09160 return vm_intro_nl(chan, vms); 09161 } else if (!strncasecmp(ast_channel_language(chan), "no", 2)) { /* NORWEGIAN syntax */ 09162 return vm_intro_no(chan, vms); 09163 } else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) { /* POLISH syntax */ 09164 return vm_intro_pl(chan, vms); 09165 } else if (!strncasecmp(ast_channel_language(chan), "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09166 return vm_intro_pt_BR(chan, vms); 09167 } else if (!strncasecmp(ast_channel_language(chan), "pt", 2)) { /* PORTUGUESE syntax */ 09168 return vm_intro_pt(chan, vms); 09169 } else if (!strncasecmp(ast_channel_language(chan), "ru", 2)) { /* RUSSIAN syntax */ 09170 return vm_intro_multilang(chan, vms, "n"); 09171 } else if (!strncasecmp(ast_channel_language(chan), "se", 2)) { /* SWEDISH syntax */ 09172 return vm_intro_se(chan, vms); 09173 } else if (!strncasecmp(ast_channel_language(chan), "ua", 2)) { /* UKRAINIAN syntax */ 09174 return vm_intro_multilang(chan, vms, "n"); 09175 } else if (!strncasecmp(ast_channel_language(chan), "vi", 2)) { /* VIETNAMESE syntax */ 09176 return vm_intro_vi(chan, vms); 09177 } else if (!strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09178 return vm_intro_zh(chan, vms); 09179 } else { /* Default to ENGLISH */ 09180 return vm_intro_en(chan, vms); 09181 } 09182 }
| static int vm_intro_cs | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8992 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08993 { 08994 int res; 08995 res = ast_play_and_wait(chan, "vm-youhave"); 08996 if (!res) { 08997 if (vms->newmessages) { 08998 if (vms->newmessages == 1) { 08999 res = ast_play_and_wait(chan, "digits/jednu"); 09000 } else { 09001 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 09002 } 09003 if (!res) { 09004 if ((vms->newmessages == 1)) 09005 res = ast_play_and_wait(chan, "vm-novou"); 09006 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 09007 res = ast_play_and_wait(chan, "vm-nove"); 09008 if (vms->newmessages > 4) 09009 res = ast_play_and_wait(chan, "vm-novych"); 09010 } 09011 if (vms->oldmessages && !res) 09012 res = ast_play_and_wait(chan, "vm-and"); 09013 else if (!res) { 09014 if ((vms->newmessages == 1)) 09015 res = ast_play_and_wait(chan, "vm-zpravu"); 09016 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 09017 res = ast_play_and_wait(chan, "vm-zpravy"); 09018 if (vms->newmessages > 4) 09019 res = ast_play_and_wait(chan, "vm-zprav"); 09020 } 09021 } 09022 if (!res && vms->oldmessages) { 09023 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 09024 if (!res) { 09025 if ((vms->oldmessages == 1)) 09026 res = ast_play_and_wait(chan, "vm-starou"); 09027 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 09028 res = ast_play_and_wait(chan, "vm-stare"); 09029 if (vms->oldmessages > 4) 09030 res = ast_play_and_wait(chan, "vm-starych"); 09031 } 09032 if (!res) { 09033 if ((vms->oldmessages == 1)) 09034 res = ast_play_and_wait(chan, "vm-zpravu"); 09035 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 09036 res = ast_play_and_wait(chan, "vm-zpravy"); 09037 if (vms->oldmessages > 4) 09038 res = ast_play_and_wait(chan, "vm-zprav"); 09039 } 09040 } 09041 if (!res) { 09042 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 09043 res = ast_play_and_wait(chan, "vm-no"); 09044 if (!res) 09045 res = ast_play_and_wait(chan, "vm-zpravy"); 09046 } 09047 } 09048 } 09049 return res; 09050 }
| static int vm_intro_de | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8688 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08689 { 08690 /* Introduce messages they have */ 08691 int res; 08692 res = ast_play_and_wait(chan, "vm-youhave"); 08693 if (!res) { 08694 if (vms->newmessages) { 08695 if ((vms->newmessages == 1)) 08696 res = ast_play_and_wait(chan, "digits/1F"); 08697 else 08698 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 08699 if (!res) 08700 res = ast_play_and_wait(chan, "vm-INBOX"); 08701 if (vms->oldmessages && !res) 08702 res = ast_play_and_wait(chan, "vm-and"); 08703 else if (!res) { 08704 if ((vms->newmessages == 1)) 08705 res = ast_play_and_wait(chan, "vm-message"); 08706 else 08707 res = ast_play_and_wait(chan, "vm-messages"); 08708 } 08709 08710 } 08711 if (!res && vms->oldmessages) { 08712 if (vms->oldmessages == 1) 08713 res = ast_play_and_wait(chan, "digits/1F"); 08714 else 08715 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 08716 if (!res) 08717 res = ast_play_and_wait(chan, "vm-Old"); 08718 if (!res) { 08719 if (vms->oldmessages == 1) 08720 res = ast_play_and_wait(chan, "vm-message"); 08721 else 08722 res = ast_play_and_wait(chan, "vm-messages"); 08723 } 08724 } 08725 if (!res) { 08726 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08727 res = ast_play_and_wait(chan, "vm-no"); 08728 if (!res) 08729 res = ast_play_and_wait(chan, "vm-messages"); 08730 } 08731 } 08732 } 08733 return res; 08734 }
| static int vm_intro_en | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8437 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08438 { 08439 int res; 08440 08441 /* Introduce messages they have */ 08442 res = ast_play_and_wait(chan, "vm-youhave"); 08443 if (!res) { 08444 if (vms->urgentmessages) { 08445 res = say_and_wait(chan, vms->urgentmessages, ast_channel_language(chan)); 08446 if (!res) 08447 res = ast_play_and_wait(chan, "vm-Urgent"); 08448 if ((vms->oldmessages || vms->newmessages) && !res) { 08449 res = ast_play_and_wait(chan, "vm-and"); 08450 } else if (!res) { 08451 if ((vms->urgentmessages == 1)) 08452 res = ast_play_and_wait(chan, "vm-message"); 08453 else 08454 res = ast_play_and_wait(chan, "vm-messages"); 08455 } 08456 } 08457 if (vms->newmessages) { 08458 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 08459 if (!res) 08460 res = ast_play_and_wait(chan, "vm-INBOX"); 08461 if (vms->oldmessages && !res) 08462 res = ast_play_and_wait(chan, "vm-and"); 08463 else if (!res) { 08464 if ((vms->newmessages == 1)) 08465 res = ast_play_and_wait(chan, "vm-message"); 08466 else 08467 res = ast_play_and_wait(chan, "vm-messages"); 08468 } 08469 08470 } 08471 if (!res && vms->oldmessages) { 08472 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 08473 if (!res) 08474 res = ast_play_and_wait(chan, "vm-Old"); 08475 if (!res) { 08476 if (vms->oldmessages == 1) 08477 res = ast_play_and_wait(chan, "vm-message"); 08478 else 08479 res = ast_play_and_wait(chan, "vm-messages"); 08480 } 08481 } 08482 if (!res) { 08483 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08484 res = ast_play_and_wait(chan, "vm-no"); 08485 if (!res) 08486 res = ast_play_and_wait(chan, "vm-messages"); 08487 } 08488 } 08489 } 08490 return res; 08491 }
| static int vm_intro_es | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8737 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08738 { 08739 /* Introduce messages they have */ 08740 int res; 08741 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08742 res = ast_play_and_wait(chan, "vm-youhaveno"); 08743 if (!res) 08744 res = ast_play_and_wait(chan, "vm-messages"); 08745 } else { 08746 res = ast_play_and_wait(chan, "vm-youhave"); 08747 } 08748 if (!res) { 08749 if (vms->newmessages) { 08750 if (!res) { 08751 if ((vms->newmessages == 1)) { 08752 res = ast_play_and_wait(chan, "digits/1M"); 08753 if (!res) 08754 res = ast_play_and_wait(chan, "vm-message"); 08755 if (!res) 08756 res = ast_play_and_wait(chan, "vm-INBOXs"); 08757 } else { 08758 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 08759 if (!res) 08760 res = ast_play_and_wait(chan, "vm-messages"); 08761 if (!res) 08762 res = ast_play_and_wait(chan, "vm-INBOX"); 08763 } 08764 } 08765 if (vms->oldmessages && !res) 08766 res = ast_play_and_wait(chan, "vm-and"); 08767 } 08768 if (vms->oldmessages) { 08769 if (!res) { 08770 if (vms->oldmessages == 1) { 08771 res = ast_play_and_wait(chan, "digits/1M"); 08772 if (!res) 08773 res = ast_play_and_wait(chan, "vm-message"); 08774 if (!res) 08775 res = ast_play_and_wait(chan, "vm-Olds"); 08776 } else { 08777 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 08778 if (!res) 08779 res = ast_play_and_wait(chan, "vm-messages"); 08780 if (!res) 08781 res = ast_play_and_wait(chan, "vm-Old"); 08782 } 08783 } 08784 } 08785 } 08786 return res; 08787 }
| static int vm_intro_fr | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8835 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08836 { 08837 /* Introduce messages they have */ 08838 int res; 08839 res = ast_play_and_wait(chan, "vm-youhave"); 08840 if (!res) { 08841 if (vms->newmessages) { 08842 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 08843 if (!res) 08844 res = ast_play_and_wait(chan, "vm-INBOX"); 08845 if (vms->oldmessages && !res) 08846 res = ast_play_and_wait(chan, "vm-and"); 08847 else if (!res) { 08848 if ((vms->newmessages == 1)) 08849 res = ast_play_and_wait(chan, "vm-message"); 08850 else 08851 res = ast_play_and_wait(chan, "vm-messages"); 08852 } 08853 08854 } 08855 if (!res && vms->oldmessages) { 08856 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 08857 if (!res) 08858 res = ast_play_and_wait(chan, "vm-Old"); 08859 if (!res) { 08860 if (vms->oldmessages == 1) 08861 res = ast_play_and_wait(chan, "vm-message"); 08862 else 08863 res = ast_play_and_wait(chan, "vm-messages"); 08864 } 08865 } 08866 if (!res) { 08867 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08868 res = ast_play_and_wait(chan, "vm-no"); 08869 if (!res) 08870 res = ast_play_and_wait(chan, "vm-messages"); 08871 } 08872 } 08873 } 08874 return res; 08875 }
| static int vm_intro_gr | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8236 of file app_voicemail.c.
References ast_channel_language(), AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08237 { 08238 int res = 0; 08239 08240 if (vms->newmessages) { 08241 res = ast_play_and_wait(chan, "vm-youhave"); 08242 if (!res) 08243 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, ast_channel_language(chan), NULL); 08244 if (!res) { 08245 if ((vms->newmessages == 1)) { 08246 res = ast_play_and_wait(chan, "vm-INBOX"); 08247 if (!res) 08248 res = ast_play_and_wait(chan, "vm-message"); 08249 } else { 08250 res = ast_play_and_wait(chan, "vm-INBOXs"); 08251 if (!res) 08252 res = ast_play_and_wait(chan, "vm-messages"); 08253 } 08254 } 08255 } else if (vms->oldmessages){ 08256 res = ast_play_and_wait(chan, "vm-youhave"); 08257 if (!res) 08258 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, ast_channel_language(chan), NULL); 08259 if ((vms->oldmessages == 1)){ 08260 res = ast_play_and_wait(chan, "vm-Old"); 08261 if (!res) 08262 res = ast_play_and_wait(chan, "vm-message"); 08263 } else { 08264 res = ast_play_and_wait(chan, "vm-Olds"); 08265 if (!res) 08266 res = ast_play_and_wait(chan, "vm-messages"); 08267 } 08268 } else if (!vms->oldmessages && !vms->newmessages) 08269 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08270 return res; 08271 }
| static int vm_intro_he | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8370 of file app_voicemail.c.
References ast_channel_language(), AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08371 { 08372 int res = 0; 08373 08374 /* Introduce messages they have */ 08375 if (!res) { 08376 if ((vms->newmessages) || (vms->oldmessages)) { 08377 res = ast_play_and_wait(chan, "vm-youhave"); 08378 } 08379 /* 08380 * The word "shtei" refers to the number 2 in hebrew when performing a count 08381 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08382 * an element, this is one of them. 08383 */ 08384 if (vms->newmessages) { 08385 if (!res) { 08386 if (vms->newmessages == 1) { 08387 res = ast_play_and_wait(chan, "vm-INBOX1"); 08388 } else { 08389 if (vms->newmessages == 2) { 08390 res = ast_play_and_wait(chan, "vm-shtei"); 08391 } else { 08392 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, ast_channel_language(chan), "f"); 08393 } 08394 res = ast_play_and_wait(chan, "vm-INBOX"); 08395 } 08396 } 08397 if (vms->oldmessages && !res) { 08398 res = ast_play_and_wait(chan, "vm-and"); 08399 if (vms->oldmessages == 1) { 08400 res = ast_play_and_wait(chan, "vm-Old1"); 08401 } else { 08402 if (vms->oldmessages == 2) { 08403 res = ast_play_and_wait(chan, "vm-shtei"); 08404 } else { 08405 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, ast_channel_language(chan), "f"); 08406 } 08407 res = ast_play_and_wait(chan, "vm-Old"); 08408 } 08409 } 08410 } 08411 if (!res && vms->oldmessages && !vms->newmessages) { 08412 if (!res) { 08413 if (vms->oldmessages == 1) { 08414 res = ast_play_and_wait(chan, "vm-Old1"); 08415 } else { 08416 if (vms->oldmessages == 2) { 08417 res = ast_play_and_wait(chan, "vm-shtei"); 08418 } else { 08419 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, ast_channel_language(chan), "f"); 08420 } 08421 res = ast_play_and_wait(chan, "vm-Old"); 08422 } 08423 } 08424 } 08425 if (!res) { 08426 if (!vms->oldmessages && !vms->newmessages) { 08427 if (!res) { 08428 res = ast_play_and_wait(chan, "vm-nomessages"); 08429 } 08430 } 08431 } 08432 } 08433 return res; 08434 }
| static int vm_intro_it | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8494 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08495 { 08496 /* Introduce messages they have */ 08497 int res; 08498 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08499 res = ast_play_and_wait(chan, "vm-no") || 08500 ast_play_and_wait(chan, "vm-message"); 08501 else 08502 res = ast_play_and_wait(chan, "vm-youhave"); 08503 if (!res && vms->newmessages) { 08504 res = (vms->newmessages == 1) ? 08505 ast_play_and_wait(chan, "digits/un") || 08506 ast_play_and_wait(chan, "vm-nuovo") || 08507 ast_play_and_wait(chan, "vm-message") : 08508 /* 2 or more new messages */ 08509 say_and_wait(chan, vms->newmessages, ast_channel_language(chan)) || 08510 ast_play_and_wait(chan, "vm-nuovi") || 08511 ast_play_and_wait(chan, "vm-messages"); 08512 if (!res && vms->oldmessages) 08513 res = ast_play_and_wait(chan, "vm-and"); 08514 } 08515 if (!res && vms->oldmessages) { 08516 res = (vms->oldmessages == 1) ? 08517 ast_play_and_wait(chan, "digits/un") || 08518 ast_play_and_wait(chan, "vm-vecchio") || 08519 ast_play_and_wait(chan, "vm-message") : 08520 /* 2 or more old messages */ 08521 say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)) || 08522 ast_play_and_wait(chan, "vm-vecchi") || 08523 ast_play_and_wait(chan, "vm-messages"); 08524 } 08525 return res; 08526 }
| static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| const char | message_gender[] | |||
| ) | [static] |
Definition at line 8330 of file app_voicemail.c.
References ast_channel_language(), 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().
08331 { 08332 int res; 08333 int lastnum = 0; 08334 08335 res = ast_play_and_wait(chan, "vm-youhave"); 08336 08337 if (!res && vms->newmessages) { 08338 lastnum = vms->newmessages; 08339 08340 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, ast_channel_language(chan), message_gender))) { 08341 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08342 } 08343 08344 if (!res && vms->oldmessages) { 08345 res = ast_play_and_wait(chan, "vm-and"); 08346 } 08347 } 08348 08349 if (!res && vms->oldmessages) { 08350 lastnum = vms->oldmessages; 08351 08352 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, ast_channel_language(chan), message_gender))) { 08353 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08354 } 08355 } 08356 08357 if (!res) { 08358 if (lastnum == 0) { 08359 res = ast_play_and_wait(chan, "vm-no"); 08360 } 08361 if (!res) { 08362 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08363 } 08364 } 08365 08366 return res; 08367 }
| static int vm_intro_nl | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8878 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08879 { 08880 /* Introduce messages they have */ 08881 int res; 08882 res = ast_play_and_wait(chan, "vm-youhave"); 08883 if (!res) { 08884 if (vms->newmessages) { 08885 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 08886 if (!res) { 08887 if (vms->newmessages == 1) 08888 res = ast_play_and_wait(chan, "vm-INBOXs"); 08889 else 08890 res = ast_play_and_wait(chan, "vm-INBOX"); 08891 } 08892 if (vms->oldmessages && !res) 08893 res = ast_play_and_wait(chan, "vm-and"); 08894 else if (!res) { 08895 if ((vms->newmessages == 1)) 08896 res = ast_play_and_wait(chan, "vm-message"); 08897 else 08898 res = ast_play_and_wait(chan, "vm-messages"); 08899 } 08900 08901 } 08902 if (!res && vms->oldmessages) { 08903 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 08904 if (!res) { 08905 if (vms->oldmessages == 1) 08906 res = ast_play_and_wait(chan, "vm-Olds"); 08907 else 08908 res = ast_play_and_wait(chan, "vm-Old"); 08909 } 08910 if (!res) { 08911 if (vms->oldmessages == 1) 08912 res = ast_play_and_wait(chan, "vm-message"); 08913 else 08914 res = ast_play_and_wait(chan, "vm-messages"); 08915 } 08916 } 08917 if (!res) { 08918 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08919 res = ast_play_and_wait(chan, "vm-no"); 08920 if (!res) 08921 res = ast_play_and_wait(chan, "vm-messages"); 08922 } 08923 } 08924 } 08925 return res; 08926 }
| static int vm_intro_no | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8644 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08645 { 08646 /* Introduce messages they have */ 08647 int res; 08648 08649 res = ast_play_and_wait(chan, "vm-youhave"); 08650 if (res) 08651 return res; 08652 08653 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08654 res = ast_play_and_wait(chan, "vm-no"); 08655 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08656 return res; 08657 } 08658 08659 if (vms->newmessages) { 08660 if ((vms->newmessages == 1)) { 08661 res = ast_play_and_wait(chan, "digits/1"); 08662 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08663 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08664 } else { 08665 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 08666 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08667 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08668 } 08669 if (!res && vms->oldmessages) 08670 res = ast_play_and_wait(chan, "vm-and"); 08671 } 08672 if (!res && vms->oldmessages) { 08673 if (vms->oldmessages == 1) { 08674 res = ast_play_and_wait(chan, "digits/1"); 08675 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08676 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08677 } else { 08678 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 08679 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08680 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08681 } 08682 } 08683 08684 return res; 08685 }
| static int vm_intro_pl | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8529 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08530 { 08531 /* Introduce messages they have */ 08532 int res; 08533 div_t num; 08534 08535 if (!vms->oldmessages && !vms->newmessages) { 08536 res = ast_play_and_wait(chan, "vm-no"); 08537 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08538 return res; 08539 } else { 08540 res = ast_play_and_wait(chan, "vm-youhave"); 08541 } 08542 08543 if (vms->newmessages) { 08544 num = div(vms->newmessages, 10); 08545 if (vms->newmessages == 1) { 08546 res = ast_play_and_wait(chan, "digits/1-a"); 08547 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08548 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08549 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08550 if (num.rem == 2) { 08551 if (!num.quot) { 08552 res = ast_play_and_wait(chan, "digits/2-ie"); 08553 } else { 08554 res = say_and_wait(chan, vms->newmessages - 2 , ast_channel_language(chan)); 08555 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08556 } 08557 } else { 08558 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 08559 } 08560 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08561 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08562 } else { 08563 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 08564 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08565 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08566 } 08567 if (!res && vms->oldmessages) 08568 res = ast_play_and_wait(chan, "vm-and"); 08569 } 08570 if (!res && vms->oldmessages) { 08571 num = div(vms->oldmessages, 10); 08572 if (vms->oldmessages == 1) { 08573 res = ast_play_and_wait(chan, "digits/1-a"); 08574 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08575 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08576 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08577 if (num.rem == 2) { 08578 if (!num.quot) { 08579 res = ast_play_and_wait(chan, "digits/2-ie"); 08580 } else { 08581 res = say_and_wait(chan, vms->oldmessages - 2 , ast_channel_language(chan)); 08582 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08583 } 08584 } else { 08585 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 08586 } 08587 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08588 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08589 } else { 08590 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 08591 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08592 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08593 } 08594 } 08595 08596 return res; 08597 }
| static int vm_intro_pt | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8929 of file app_voicemail.c.
References ast_channel_language(), AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
08930 { 08931 /* Introduce messages they have */ 08932 int res; 08933 res = ast_play_and_wait(chan, "vm-youhave"); 08934 if (!res) { 08935 if (vms->newmessages) { 08936 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, ast_channel_language(chan), "f"); 08937 if (!res) { 08938 if ((vms->newmessages == 1)) { 08939 res = ast_play_and_wait(chan, "vm-message"); 08940 if (!res) 08941 res = ast_play_and_wait(chan, "vm-INBOXs"); 08942 } else { 08943 res = ast_play_and_wait(chan, "vm-messages"); 08944 if (!res) 08945 res = ast_play_and_wait(chan, "vm-INBOX"); 08946 } 08947 } 08948 if (vms->oldmessages && !res) 08949 res = ast_play_and_wait(chan, "vm-and"); 08950 } 08951 if (!res && vms->oldmessages) { 08952 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, ast_channel_language(chan), "f"); 08953 if (!res) { 08954 if (vms->oldmessages == 1) { 08955 res = ast_play_and_wait(chan, "vm-message"); 08956 if (!res) 08957 res = ast_play_and_wait(chan, "vm-Olds"); 08958 } else { 08959 res = ast_play_and_wait(chan, "vm-messages"); 08960 if (!res) 08961 res = ast_play_and_wait(chan, "vm-Old"); 08962 } 08963 } 08964 } 08965 if (!res) { 08966 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08967 res = ast_play_and_wait(chan, "vm-no"); 08968 if (!res) 08969 res = ast_play_and_wait(chan, "vm-messages"); 08970 } 08971 } 08972 } 08973 return res; 08974 }
| static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8790 of file app_voicemail.c.
References ast_channel_language(), AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
08790 { 08791 /* Introduce messages they have */ 08792 int res; 08793 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08794 res = ast_play_and_wait(chan, "vm-nomessages"); 08795 return res; 08796 } else { 08797 res = ast_play_and_wait(chan, "vm-youhave"); 08798 } 08799 if (vms->newmessages) { 08800 if (!res) 08801 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, ast_channel_language(chan), "f"); 08802 if ((vms->newmessages == 1)) { 08803 if (!res) 08804 res = ast_play_and_wait(chan, "vm-message"); 08805 if (!res) 08806 res = ast_play_and_wait(chan, "vm-INBOXs"); 08807 } else { 08808 if (!res) 08809 res = ast_play_and_wait(chan, "vm-messages"); 08810 if (!res) 08811 res = ast_play_and_wait(chan, "vm-INBOX"); 08812 } 08813 if (vms->oldmessages && !res) 08814 res = ast_play_and_wait(chan, "vm-and"); 08815 } 08816 if (vms->oldmessages) { 08817 if (!res) 08818 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, ast_channel_language(chan), "f"); 08819 if (vms->oldmessages == 1) { 08820 if (!res) 08821 res = ast_play_and_wait(chan, "vm-message"); 08822 if (!res) 08823 res = ast_play_and_wait(chan, "vm-Olds"); 08824 } else { 08825 if (!res) 08826 res = ast_play_and_wait(chan, "vm-messages"); 08827 if (!res) 08828 res = ast_play_and_wait(chan, "vm-Old"); 08829 } 08830 } 08831 return res; 08832 }
| static int vm_intro_se | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8600 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08601 { 08602 /* Introduce messages they have */ 08603 int res; 08604 08605 res = ast_play_and_wait(chan, "vm-youhave"); 08606 if (res) 08607 return res; 08608 08609 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08610 res = ast_play_and_wait(chan, "vm-no"); 08611 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08612 return res; 08613 } 08614 08615 if (vms->newmessages) { 08616 if ((vms->newmessages == 1)) { 08617 res = ast_play_and_wait(chan, "digits/ett"); 08618 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08619 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08620 } else { 08621 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 08622 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08623 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08624 } 08625 if (!res && vms->oldmessages) 08626 res = ast_play_and_wait(chan, "vm-and"); 08627 } 08628 if (!res && vms->oldmessages) { 08629 if (vms->oldmessages == 1) { 08630 res = ast_play_and_wait(chan, "digits/ett"); 08631 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08632 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08633 } else { 08634 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 08635 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08636 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08637 } 08638 } 08639 08640 return res; 08641 }
| static int vm_intro_vi | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 9092 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
09093 { 09094 int res; 09095 09096 /* Introduce messages they have */ 09097 res = ast_play_and_wait(chan, "vm-youhave"); 09098 if (!res) { 09099 if (vms->newmessages) { 09100 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 09101 if (!res) 09102 res = ast_play_and_wait(chan, "vm-INBOX"); 09103 if (vms->oldmessages && !res) 09104 res = ast_play_and_wait(chan, "vm-and"); 09105 } 09106 if (!res && vms->oldmessages) { 09107 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 09108 if (!res) 09109 res = ast_play_and_wait(chan, "vm-Old"); 09110 } 09111 if (!res) { 09112 if (!vms->oldmessages && !vms->newmessages) { 09113 res = ast_play_and_wait(chan, "vm-no"); 09114 if (!res) 09115 res = ast_play_and_wait(chan, "vm-message"); 09116 } 09117 } 09118 } 09119 return res; 09120 }
| static int vm_intro_zh | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 9053 of file app_voicemail.c.
References ast_channel_language(), ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
09054 { 09055 int res; 09056 /* Introduce messages they have */ 09057 res = ast_play_and_wait(chan, "vm-you"); 09058 09059 if (!res && vms->newmessages) { 09060 res = ast_play_and_wait(chan, "vm-have"); 09061 if (!res) 09062 res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan)); 09063 if (!res) 09064 res = ast_play_and_wait(chan, "vm-tong"); 09065 if (!res) 09066 res = ast_play_and_wait(chan, "vm-INBOX"); 09067 if (vms->oldmessages && !res) 09068 res = ast_play_and_wait(chan, "vm-and"); 09069 else if (!res) 09070 res = ast_play_and_wait(chan, "vm-messages"); 09071 } 09072 if (!res && vms->oldmessages) { 09073 res = ast_play_and_wait(chan, "vm-have"); 09074 if (!res) 09075 res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan)); 09076 if (!res) 09077 res = ast_play_and_wait(chan, "vm-tong"); 09078 if (!res) 09079 res = ast_play_and_wait(chan, "vm-Old"); 09080 if (!res) 09081 res = ast_play_and_wait(chan, "vm-messages"); 09082 } 09083 if (!res && !vms->oldmessages && !vms->newmessages) { 09084 res = ast_play_and_wait(chan, "vm-haveno"); 09085 if (!res) 09086 res = ast_play_and_wait(chan, "vm-messages"); 09087 } 09088 return res; 09089 }
| 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 3356 of file app_voicemail.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
03357 { 03358 switch (ast_lock_path(path)) { 03359 case AST_LOCK_TIMEOUT: 03360 return -1; 03361 default: 03362 return 0; 03363 } 03364 }
| static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1757 of file app_voicemail.c.
References VOICEMAIL_FILE_MODE.
Referenced by sendmail(), and sendpage().
01758 { 01759 FILE *p = NULL; 01760 int pfd = mkstemp(template); 01761 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01762 if (pfd > -1) { 01763 p = fdopen(pfd, "w+"); 01764 if (!p) { 01765 close(pfd); 01766 pfd = -1; 01767 } 01768 } 01769 return p; 01770 }
| 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 9295 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, play_record_review(), 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, and vm_reenterpassword.
Referenced by vm_execmain().
09296 { 09297 int cmd = 0; 09298 int duration = 0; 09299 int tries = 0; 09300 char newpassword[80] = ""; 09301 char newpassword2[80] = ""; 09302 char prefile[PATH_MAX] = ""; 09303 unsigned char buf[256]; 09304 int bytes = 0; 09305 09306 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09307 if (ast_adsi_available(chan)) { 09308 bytes += adsi_logo(buf + bytes); 09309 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09310 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09311 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09312 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09313 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09314 } 09315 09316 /* If forcename is set, have the user record their name */ 09317 if (ast_test_flag(vmu, VM_FORCENAME)) { 09318 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09319 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09320 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09321 if (cmd < 0 || cmd == 't' || cmd == '#') 09322 return cmd; 09323 } 09324 } 09325 09326 /* If forcegreetings is set, have the user record their greetings */ 09327 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09328 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09329 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09330 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09331 if (cmd < 0 || cmd == 't' || cmd == '#') 09332 return cmd; 09333 } 09334 09335 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09336 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09337 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09338 if (cmd < 0 || cmd == 't' || cmd == '#') 09339 return cmd; 09340 } 09341 } 09342 09343 /* 09344 * Change the password last since new users will be able to skip over any steps this one comes before 09345 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09346 */ 09347 for (;;) { 09348 newpassword[1] = '\0'; 09349 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09350 if (cmd == '#') 09351 newpassword[0] = '\0'; 09352 if (cmd < 0 || cmd == 't' || cmd == '#') 09353 return cmd; 09354 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09355 if (cmd < 0 || cmd == 't' || cmd == '#') 09356 return cmd; 09357 cmd = check_password(vmu, newpassword); /* perform password validation */ 09358 if (cmd != 0) { 09359 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09360 cmd = ast_play_and_wait(chan, vm_invalid_password); 09361 } else { 09362 newpassword2[1] = '\0'; 09363 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09364 if (cmd == '#') 09365 newpassword2[0] = '\0'; 09366 if (cmd < 0 || cmd == 't' || cmd == '#') 09367 return cmd; 09368 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09369 if (cmd < 0 || cmd == 't' || cmd == '#') 09370 return cmd; 09371 if (!strcmp(newpassword, newpassword2)) 09372 break; 09373 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09374 cmd = ast_play_and_wait(chan, vm_mismatch); 09375 } 09376 if (++tries == 3) 09377 return -1; 09378 if (cmd != 0) { 09379 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09380 } 09381 } 09382 if (pwdchange & PWDCHANGE_INTERNAL) 09383 vm_change_password(vmu, newpassword); 09384 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09385 vm_change_password_shell(vmu, newpassword); 09386 09387 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09388 cmd = ast_play_and_wait(chan, vm_passchanged); 09389 09390 return cmd; 09391 }
| 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 9393 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, ast_vm_user::mailbox, ast_vm_user::password, play_record_review(), 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, and vm_tempgreeting().
Referenced by vm_execmain().
09394 { 09395 int cmd = 0; 09396 int retries = 0; 09397 int duration = 0; 09398 char newpassword[80] = ""; 09399 char newpassword2[80] = ""; 09400 char prefile[PATH_MAX] = ""; 09401 unsigned char buf[256]; 09402 int bytes = 0; 09403 09404 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09405 if (ast_adsi_available(chan)) { 09406 bytes += adsi_logo(buf + bytes); 09407 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09408 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09409 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09410 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09411 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09412 } 09413 while ((cmd >= 0) && (cmd != 't')) { 09414 if (cmd) 09415 retries = 0; 09416 switch (cmd) { 09417 case '1': /* Record your unavailable message */ 09418 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09419 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09420 break; 09421 case '2': /* Record your busy message */ 09422 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09423 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09424 break; 09425 case '3': /* Record greeting */ 09426 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09427 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09428 break; 09429 case '4': /* manage the temporary greeting */ 09430 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09431 break; 09432 case '5': /* change password */ 09433 if (vmu->password[0] == '-') { 09434 cmd = ast_play_and_wait(chan, "vm-no"); 09435 break; 09436 } 09437 newpassword[1] = '\0'; 09438 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09439 if (cmd == '#') 09440 newpassword[0] = '\0'; 09441 else { 09442 if (cmd < 0) 09443 break; 09444 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09445 break; 09446 } 09447 } 09448 cmd = check_password(vmu, newpassword); /* perform password validation */ 09449 if (cmd != 0) { 09450 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09451 cmd = ast_play_and_wait(chan, vm_invalid_password); 09452 if (!cmd) { 09453 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09454 } 09455 break; 09456 } 09457 newpassword2[1] = '\0'; 09458 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09459 if (cmd == '#') 09460 newpassword2[0] = '\0'; 09461 else { 09462 if (cmd < 0) 09463 break; 09464 09465 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09466 break; 09467 } 09468 } 09469 if (strcmp(newpassword, newpassword2)) { 09470 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09471 cmd = ast_play_and_wait(chan, vm_mismatch); 09472 if (!cmd) { 09473 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09474 } 09475 break; 09476 } 09477 09478 if (pwdchange & PWDCHANGE_INTERNAL) { 09479 vm_change_password(vmu, newpassword); 09480 } 09481 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09482 vm_change_password_shell(vmu, newpassword); 09483 } 09484 09485 ast_debug(1, "User %s set password to %s of length %d\n", 09486 vms->username, newpassword, (int) strlen(newpassword)); 09487 cmd = ast_play_and_wait(chan, vm_passchanged); 09488 break; 09489 case '*': 09490 cmd = 't'; 09491 break; 09492 default: 09493 cmd = 0; 09494 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09495 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09496 if (ast_fileexists(prefile, NULL, NULL)) { 09497 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09498 } 09499 DISPOSE(prefile, -1); 09500 if (!cmd) { 09501 cmd = ast_play_and_wait(chan, "vm-options"); 09502 } 09503 if (!cmd) { 09504 cmd = ast_waitfordigit(chan, 6000); 09505 } 09506 if (!cmd) { 09507 retries++; 09508 } 09509 if (retries > 3) { 09510 cmd = 't'; 09511 } 09512 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09513 } 09514 } 09515 if (cmd == 't') 09516 cmd = 0; 09517 return cmd; 09518 }
| static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
| char * | mbox | |||
| ) | [static] |
Definition at line 8199 of file app_voicemail.c.
References ast_channel_language(), 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().
08200 { 08201 int cmd; 08202 08203 if ( !strncasecmp(ast_channel_language(chan), "it", 2) || 08204 !strncasecmp(ast_channel_language(chan), "es", 2) || 08205 !strncasecmp(ast_channel_language(chan), "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08206 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08207 return cmd ? cmd : ast_play_and_wait(chan, box); 08208 } else if (!strncasecmp(ast_channel_language(chan), "gr", 2)) { 08209 return vm_play_folder_name_gr(chan, box); 08210 } else if (!strncasecmp(ast_channel_language(chan), "he", 2)) { /* Hebrew syntax */ 08211 return ast_play_and_wait(chan, box); 08212 } else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) { 08213 return vm_play_folder_name_pl(chan, box); 08214 } else if (!strncasecmp(ast_channel_language(chan), "ua", 2)) { /* Ukrainian syntax */ 08215 return vm_play_folder_name_ua(chan, box); 08216 } else if (!strncasecmp(ast_channel_language(chan), "vi", 2)) { 08217 return ast_play_and_wait(chan, box); 08218 } else { /* Default English */ 08219 cmd = ast_play_and_wait(chan, box); 08220 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08221 } 08222 }
| static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 8152 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08153 { 08154 int cmd; 08155 char *buf; 08156 08157 buf = alloca(strlen(box) + 2); 08158 strcpy(buf, box); 08159 strcat(buf, "s"); 08160 08161 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08162 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08163 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08164 } else { 08165 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08166 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08167 } 08168 }
| static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 8170 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08171 { 08172 int cmd; 08173 08174 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08175 if (!strcasecmp(box, "vm-INBOX")) 08176 cmd = ast_play_and_wait(chan, "vm-new-e"); 08177 else 08178 cmd = ast_play_and_wait(chan, "vm-old-e"); 08179 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08180 } else { 08181 cmd = ast_play_and_wait(chan, "vm-messages"); 08182 return cmd ? cmd : ast_play_and_wait(chan, box); 08183 } 08184 }
| static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 8186 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08187 { 08188 int cmd; 08189 08190 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08191 cmd = ast_play_and_wait(chan, "vm-messages"); 08192 return cmd ? cmd : ast_play_and_wait(chan, box); 08193 } else { 08194 cmd = ast_play_and_wait(chan, box); 08195 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08196 } 08197 }
| 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 9536 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, play_record_review(), RETRIEVE, and vm_state::username.
Referenced by vm_options().
09537 { 09538 int cmd = 0; 09539 int retries = 0; 09540 int duration = 0; 09541 char prefile[PATH_MAX] = ""; 09542 unsigned char buf[256]; 09543 int bytes = 0; 09544 09545 if (ast_adsi_available(chan)) { 09546 bytes += adsi_logo(buf + bytes); 09547 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09548 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09549 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09550 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09551 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09552 } 09553 09554 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09555 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09556 while ((cmd >= 0) && (cmd != 't')) { 09557 if (cmd) 09558 retries = 0; 09559 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09560 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09561 play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09562 cmd = 't'; 09563 } else { 09564 switch (cmd) { 09565 case '1': 09566 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09567 break; 09568 case '2': 09569 DELETE(prefile, -1, prefile, vmu); 09570 ast_play_and_wait(chan, "vm-tempremoved"); 09571 cmd = 't'; 09572 break; 09573 case '*': 09574 cmd = 't'; 09575 break; 09576 default: 09577 cmd = ast_play_and_wait(chan, 09578 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09579 "vm-tempgreeting2" : "vm-tempgreeting"); 09580 if (!cmd) { 09581 cmd = ast_waitfordigit(chan, 6000); 09582 } 09583 if (!cmd) { 09584 retries++; 09585 } 09586 if (retries > 3) { 09587 cmd = 't'; 09588 } 09589 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09590 } 09591 } 09592 DISPOSE(prefile, -1); 09593 } 09594 if (cmd == 't') 09595 cmd = 0; 09596 return cmd; 09597 }
| static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 11581 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and vm_users_data_provider_get_helper().
11583 { 11584 struct ast_vm_user *user; 11585 11586 AST_LIST_LOCK(&users); 11587 AST_LIST_TRAVERSE(&users, user, list) { 11588 vm_users_data_provider_get_helper(search, data_root, user); 11589 } 11590 AST_LIST_UNLOCK(&users); 11591 11592 return 0; 11593 }
| 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 11534 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, vm_zone::name, and ast_vm_user::zonetag.
Referenced by vm_users_data_provider_get().
11536 { 11537 struct ast_data *data_user, *data_zone; 11538 struct ast_data *data_state; 11539 struct vm_zone *zone = NULL; 11540 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11541 char ext_context[256] = ""; 11542 11543 data_user = ast_data_add_node(data_root, "user"); 11544 if (!data_user) { 11545 return -1; 11546 } 11547 11548 ast_data_add_structure(ast_vm_user, data_user, user); 11549 11550 AST_LIST_LOCK(&zones); 11551 AST_LIST_TRAVERSE(&zones, zone, list) { 11552 if (!strcmp(zone->name, user->zonetag)) { 11553 break; 11554 } 11555 } 11556 AST_LIST_UNLOCK(&zones); 11557 11558 /* state */ 11559 data_state = ast_data_add_node(data_user, "state"); 11560 if (!data_state) { 11561 return -1; 11562 } 11563 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11564 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11565 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11566 ast_data_add_int(data_state, "newmsg", newmsg); 11567 ast_data_add_int(data_state, "oldmsg", oldmsg); 11568 11569 if (zone) { 11570 data_zone = ast_data_add_node(data_user, "zone"); 11571 ast_data_add_structure(vm_zone, data_zone, zone); 11572 } 11573 11574 if (!ast_data_search_match(search, data_user)) { 11575 ast_data_remove_node(data_root, data_user); 11576 } 11577 11578 return 0; 11579 }
| static int vmauthenticate | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 11220 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(), strsep(), and vm_authenticate().
Referenced by load_module().
11221 { 11222 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11223 struct ast_vm_user vmus; 11224 char *options = NULL; 11225 int silent = 0, skipuser = 0; 11226 int res = -1; 11227 11228 if (data) { 11229 s = ast_strdupa(data); 11230 user = strsep(&s, ","); 11231 options = strsep(&s, ","); 11232 if (user) { 11233 s = user; 11234 user = strsep(&s, "@"); 11235 context = strsep(&s, ""); 11236 if (!ast_strlen_zero(user)) 11237 skipuser++; 11238 ast_copy_string(mailbox, user, sizeof(mailbox)); 11239 } 11240 } 11241 11242 if (options) { 11243 silent = (strchr(options, 's')) != NULL; 11244 } 11245 11246 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11247 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11248 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11249 ast_play_and_wait(chan, "auth-thankyou"); 11250 res = 0; 11251 } else if (mailbox[0] == '*') { 11252 /* user entered '*' */ 11253 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11254 res = 0; /* prevent hangup */ 11255 } 11256 } 11257 11258 return res; 11259 }
| static int vmsayname_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 12745 of file app_voicemail.c.
References ast_channel_language(), 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().
12746 { 12747 char *context; 12748 char *args_copy; 12749 int res; 12750 12751 if (ast_strlen_zero(data)) { 12752 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context"); 12753 return -1; 12754 } 12755 12756 args_copy = ast_strdupa(data); 12757 if ((context = strchr(args_copy, '@'))) { 12758 *context++ = '\0'; 12759 } else { 12760 context = "default"; 12761 } 12762 12763 if ((res = sayname(chan, args_copy, context)) < 0) { 12764 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12765 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12766 if (!res) { 12767 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, ast_channel_language(chan)); 12768 } 12769 } 12770 12771 return res; 12772 }
| 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 4509 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_strlen_zero(), ast_tvnow(), vm_zone::name, vm_zone::timezone, and ast_vm_user::zonetag.
Referenced by make_email_file(), and sendpage().
04510 { 04511 const struct vm_zone *z = NULL; 04512 struct timeval t = ast_tvnow(); 04513 04514 /* Does this user have a timezone specified? */ 04515 if (!ast_strlen_zero(vmu->zonetag)) { 04516 /* Find the zone in the list */ 04517 AST_LIST_LOCK(&zones); 04518 AST_LIST_TRAVERSE(&zones, z, list) { 04519 if (!strcmp(z->name, vmu->zonetag)) 04520 break; 04521 } 04522 AST_LIST_UNLOCK(&zones); 04523 } 04524 ast_localtime(&t, tm, z ? z->timezone : NULL); 04525 return tm; 04526 }
| static int wait_file | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | file | |||
| ) | [static] |
Definition at line 7547 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, and listen_control_stop_key.
Referenced by advanced_options(), ast_say_date_da(), ast_say_date_de(), ast_say_date_pt(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_es(), ast_say_date_with_format_fr(), ast_say_date_with_format_gr(), ast_say_date_with_format_he(), ast_say_date_with_format_it(), ast_say_date_with_format_nl(), ast_say_date_with_format_pl(), ast_say_date_with_format_pt(), ast_say_date_with_format_th(), ast_say_date_with_format_vi(), ast_say_date_with_format_zh(), ast_say_datetime_from_now_pt(), ast_say_number_full_pt(), ast_say_time_pt(), ast_say_time_pt_BR(), gr_say_number_female(), and play_message().
07548 { 07549 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07550 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); 07551 }
| static int wait_file2 | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | file | |||
| ) | [static] |
Definition at line 7539 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().
07540 { 07541 int res; 07542 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07543 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07544 return res; 07545 }
| static int write_password_to_file | ( | const char * | secretfn, | |
| const char * | password | |||
| ) | [static] |
Definition at line 12719 of file app_voicemail.c.
References ast_category_append(), ast_category_new(), ast_config_new(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), and LOG_ERROR.
Referenced by vm_change_password().
12719 { 12720 struct ast_config *conf; 12721 struct ast_category *cat; 12722 struct ast_variable *var; 12723 12724 if (!(conf=ast_config_new())) { 12725 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12726 return -1; 12727 } 12728 if (!(cat=ast_category_new("general","",1))) { 12729 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12730 return -1; 12731 } 12732 if (!(var=ast_variable_new("password",password,""))) { 12733 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12734 return -1; 12735 } 12736 ast_category_append(conf,cat); 12737 ast_variable_append(cat,var); 12738 if (ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12739 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12740 return -1; 12741 } 12742 return 0; 12743 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } [static] |
Definition at line 13910 of file app_voicemail.c.
char* addesc = "Comedian Mail" [static] |
Definition at line 844 of file app_voicemail.c.
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 971 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 972 of file app_voicemail.c.
Referenced by actual_load_config(), and adsi_load_vmail().
int adsiver = 1 [static] |
Definition at line 973 of file app_voicemail.c.
Referenced by actual_load_config(), adsi_begin(), and adsi_load_vmail().
char* app = "VoiceMail" [static] |
Definition at line 847 of file app_voicemail.c.
char* app2 = "VoiceMailMain" [static] |
Definition at line 850 of file app_voicemail.c.
char* app3 = "MailboxExists" [static] |
Definition at line 852 of file app_voicemail.c.
char* app4 = "VMAuthenticate" [static] |
Definition at line 853 of file app_voicemail.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 13910 of file app_voicemail.c.
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 957 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char charset[32] = "ISO-8859-1" [static] |
Definition at line 969 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 960 of file app_voicemail.c.
Referenced by actual_load_config(), and play_message_callerid().
struct ast_cli_entry cli_voicemail[] [static] |
Initial value:
{
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 11457 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 956 of file app_voicemail.c.
Referenced by actual_load_config(), directory_exec(), and populate_defaults().
char* emailbody = NULL [static] |
Definition at line 963 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 974 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 964 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
char exitcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 958 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 824 of file app_voicemail.c.
char ext_pass_cmd[128] [static] |
Definition at line 823 of file app_voicemail.c.
char externnotify[160] [static] |
Definition at line 867 of file app_voicemail.c.
char fromstring[100] [static] |
Definition at line 967 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
struct ast_flags globalflags = {0} [static] |
Definition at line 952 of file app_voicemail.c.
| struct ao2_container* inprocess_container |
Definition at line 995 of file app_voicemail.c.
Referenced by inprocess_count(), load_module(), and unload_module().
char listen_control_forward_key[12] [static] |
Definition at line 922 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_pause_key[12] [static] |
Definition at line 927 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_restart_key[12] [static] |
Definition at line 928 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_reverse_key[12] [static] |
Definition at line 926 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_stop_key[12] [static] |
Definition at line 929 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char locale[20] [static] |
Definition at line 860 of file app_voicemail.c.
struct ast_custom_function mailbox_exists_acf [static] |
Initial value:
{
.name = "MAILBOX_EXISTS",
.read = acf_mailbox_exists,
}
Definition at line 11210 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
const char* const mailbox_folders[] [static] |
char mailcmd[160] [static] |
Definition at line 866 of file app_voicemail.c.
int maxdeletedmsg [static] |
Definition at line 863 of file app_voicemail.c.
int maxgreet [static] |
Definition at line 873 of file app_voicemail.c.
int maxlogins [static] |
Definition at line 875 of file app_voicemail.c.
int maxmsg [static] |
Definition at line 862 of file app_voicemail.c.
int maxsilence [static] |
int minpassword [static] |
Definition at line 876 of file app_voicemail.c.
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 894 of file app_voicemail.c.
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 920 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 896 of file app_voicemail.c.
int my_umask [static] |
Definition at line 826 of file app_voicemail.c.
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] |
Definition at line 877 of file app_voicemail.c.
ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 889 of file app_voicemail.c.
unsigned int poll_freq [static] |
Polling frequency
Definition at line 884 of file app_voicemail.c.
ast_mutex_t poll_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static] |
Definition at line 888 of file app_voicemail.c.
Referenced by mb_poll_thread(), and stop_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 881 of file app_voicemail.c.
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 890 of file app_voicemail.c.
unsigned char poll_thread_run [static] |
Definition at line 891 of file app_voicemail.c.
int pwdchange = PWDCHANGE_INTERNAL [static] |
Definition at line 830 of file app_voicemail.c.
int saydurationminfo [static] |
Definition at line 954 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char* sayname_app = "VMSayName" [static] |
Definition at line 855 of file app_voicemail.c.
char serveremail[80] [static] |
Definition at line 865 of file app_voicemail.c.
int silencethreshold = 128 [static] |
Definition at line 864 of file app_voicemail.c.
Referenced by ast_record_review(), and setup_privacy_args().
int skipms [static] |
Definition at line 874 of file app_voicemail.c.
Referenced by controlplayback_exec(), and handle_controlstreamfile().
struct ast_smdi_interface* smdi_iface = NULL [static] |
Definition at line 868 of file app_voicemail.c.
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 842 of file app_voicemail.c.
struct ast_app_option vm_app_options[128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'd' ] = { .flag = OPT_DTMFEXIT , .arg_index = OPT_ARG_DTMFEXIT + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 }, [ 'U' ] = { .flag = OPT_MESSAGE_Urgent }, [ 'P' ] = { .flag = OPT_MESSAGE_PRIORITY }} [static] |
struct ast_data_entry vm_data_providers[] [static] |
struct ast_custom_function vm_info_acf [static] |
Initial value:
{
.name = "VM_INFO",
.read = acf_vm_info,
}
Definition at line 11215 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char vm_invalid_password[80] = "vm-invalid-password" [static] |
Definition at line 937 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 936 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 933 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 934 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 932 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 938 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 950 of file app_voicemail.c.
Referenced by actual_load_config(), and vm_forwardoptions().
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 935 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 821 of file app_voicemail.c.
struct ast_data_handler vm_users_data_provider [static] |
Initial value:
{
.version = AST_DATA_HANDLER_VERSION,
.get = vm_users_data_provider_get
}
Definition at line 11595 of file app_voicemail.c.
char vmfmts[80] [static] |
Definition at line 869 of file app_voicemail.c.
int vmmaxsecs [static] |
Definition at line 872 of file app_voicemail.c.
int vmminsecs [static] |
Definition at line 871 of file app_voicemail.c.
double volgain [static] |
Definition at line 870 of file app_voicemail.c.
char zonetag[80] [static] |
1.5.6