Comedian Mail - Voicemail System. More...
#include "asterisk.h"#include "asterisk/paths.h"#include <sys/time.h>#include <sys/stat.h>#include <sys/mman.h>#include <time.h>#include <dirent.h>#include "asterisk/logger.h"#include "asterisk/lock.h"#include "asterisk/file.h"#include "asterisk/channel.h"#include "asterisk/pbx.h"#include "asterisk/config.h"#include "asterisk/say.h"#include "asterisk/module.h"#include "asterisk/adsi.h"#include "asterisk/app.h"#include "asterisk/manager.h"#include "asterisk/dsp.h"#include "asterisk/localtime.h"#include "asterisk/cli.h"#include "asterisk/utils.h"#include "asterisk/stringfields.h"#include "asterisk/smdi.h"#include "asterisk/event.h"#include "asterisk/taskprocessor.h"
Go to the source code of this file.
Data Structures | |
| struct | ast_vm_user |
| struct | baseio |
| 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 |
| 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 | 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 | eol "\r\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 | 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 | { NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER } |
| enum | { 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 | { OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3 } |
Functions | |
| static int | __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit) |
| 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 | 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. | |
| 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 char * | encode_mime_str (const char *start, char *end, size_t endsize, 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 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 | 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 | 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 (int id) |
| static int | messagecount (const char *context, const char *mailbox, const char *folder) |
| static void | mwi_sub_destroy (struct mwi_sub *mwi_sub) |
| static void | mwi_sub_event_cb (const struct ast_event *event, void *userdata) |
| static void | mwi_unsub_event_cb (const struct ast_event *event, void *userdata) |
| static int | notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag) |
| Sends email notification that a user has a new voicemail waiting for them. | |
| static int | ochar (struct baseio *bio, int c, FILE *so) |
| utility used by base_encode() | |
| static int | open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box) |
| static int | play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
| static int | play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback) |
| static int | play_message_category (struct ast_channel *chan, const char *category) |
| static int | play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename) |
| static int | play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration) |
| static int | play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, 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, char *passdata, size_t passdatasize, const char *category, const char *flag) |
| static void | queue_mwi_event (const char *box, int urgent, int new, int old) |
| static char * | quote (const char *from, char *to, size_t len) |
| Wraps a character sequence in double quotes, escaping occurences of quotes within the string. | |
| static int | reload (void) |
| static void | rename_file (char *sfn, char *dfn) |
| Renames a message in a mailbox folder. | |
| 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 char * | substitute_escapes (const char *value) |
| static int | unload_module (void) |
| 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, void *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_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, void *data) |
| static int | vm_execmain (struct ast_channel *chan, void *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_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 | vmauthenticate (struct ast_channel *chan, void *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. Return tm so it can be used as a function argument. | |
| 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) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "DAHDI Telephony w/PRI & SS7" , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } |
| 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 * | descrip_vm |
| static char * | descrip_vm_box_exists |
| static char * | descrip_vmain |
| static char * | descrip_vmauthenticate |
| 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} |
| 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 struct ast_custom_function | mailbox_exists_acf |
| 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 | pagerfromstring [100] |
| static char * | pagersubject = NULL |
| static ast_cond_t | poll_cond = PTHREAD_COND_INITIALIZER |
| static unsigned int | poll_freq |
| static ast_mutex_t | poll_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
| 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 | serveremail [80] |
| static int | silencethreshold = 128 |
| static int | skipms |
| static struct ast_smdi_interface * | smdi_iface = NULL |
| static char * | synopsis_vm = "Leave a Voicemail message" |
| static char * | synopsis_vm_box_exists |
| static char * | synopsis_vmain = "Check Voicemail messages" |
| static char * | synopsis_vmauthenticate = "Authenticate with Voicemail passwords" |
| 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 }} |
| enum { ... } | vm_box |
| static char | vm_invalid_password [80] = "vm-invalid-password" |
| static char | vm_mismatch [80] = "vm-mismatch" |
| static char | vm_newpassword [80] = "vm-newpassword" |
| enum { ... } | vm_option_args |
| enum { ... } | vm_option_flags |
| 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_reenterpassword [80] = "vm-reenterpassword" |
| static char | VM_SPOOL_DIR [PATH_MAX] |
| static char | vmfmts [80] |
| static int | vmmaxsecs |
| static int | vmminsecs |
| static double | volgain |
| static char | zonetag [80] |
Comedian Mail - Voicemail System.
Definition in file app_voicemail.c.
| #define ASTERISK_USERNAME "asterisk" |
Definition at line 191 of file app_voicemail.c.
| #define BASELINELEN 72 |
Definition at line 214 of file app_voicemail.c.
Referenced by ochar().
| #define BASEMAXINLINE 256 |
Definition at line 215 of file app_voicemail.c.
Referenced by base_encode(), and inbuf().
| #define CHUNKSIZE 65536 |
Definition at line 188 of file app_voicemail.c.
| #define COMMAND_TIMEOUT 5000 |
Definition at line 184 of file app_voicemail.c.
| #define COPY | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h | ) | (copy_plain_file(g,h)); |
Definition at line 479 of file app_voicemail.c.
Referenced by copy_message(), and save_to_folder().
| #define DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
Definition at line 196 of file app_voicemail.c.
Referenced by load_config().
| #define DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
Definition at line 198 of file app_voicemail.c.
Referenced by load_config().
| #define DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
Definition at line 199 of file app_voicemail.c.
Referenced by load_config().
| #define DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
Definition at line 197 of file app_voicemail.c.
Referenced by load_config().
| #define DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
Definition at line 200 of file app_voicemail.c.
Referenced by load_config().
| #define DEFAULT_POLL_FREQ 30 |
By default, poll every 30 seconds
Definition at line 627 of file app_voicemail.c.
Referenced by load_config().
| #define DELETE | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (vm_delete(c)) |
Definition at line 480 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 475 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" |
Referenced by add_email_attachment(), and make_email_file().
| #define eol "\r\n" |
Definition at line 216 of file app_voicemail.c.
Referenced by base_encode(), and ochar().
| #define ERROR_LOCK_PATH -100 |
Definition at line 240 of file app_voicemail.c.
| #define EXISTS | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 477 of file app_voicemail.c.
Referenced by close_mailbox(), copy_message(), 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 207 of file app_voicemail.c.
Referenced by leave_voicemail(), play_record_review(), and vm_forwardoptions().
| #define MAX_DATETIME_FORMAT 512 |
Definition at line 218 of file app_voicemail.c.
| #define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 219 of file app_voicemail.c.
| #define MAXMSG 100 |
Definition at line 209 of file app_voicemail.c.
Referenced by apply_option(), and load_config().
| #define MAXMSGLIMIT 9999 |
Definition at line 210 of file app_voicemail.c.
Referenced by apply_option(), last_message_index(), and load_config().
| #define MINPASSWORD 0 |
Default minimum mailbox password length
Definition at line 212 of file app_voicemail.c.
Referenced by load_config().
| #define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 492 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
| #define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 491 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
| #define RENAME | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h | ) | (rename_file(g,h)); |
Definition at line 478 of file app_voicemail.c.
Referenced by close_mailbox(), leave_voicemail(), and save_to_folder().
| #define RETRIEVE | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) |
Definition at line 474 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 205 of file app_voicemail.c.
| #define SMDI_MWI_WAIT_TIMEOUT 1000 |
Definition at line 182 of file app_voicemail.c.
Referenced by run_externnotify().
| #define STORE | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h, | |||||
| i, | |||||
| j | ) |
Definition at line 476 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 501 of file app_voicemail.c.
| #define VALID_DTMF "1234567890*#" |
Definition at line 201 of file app_voicemail.c.
Referenced by is_valid_dtmf().
| #define VM_ALLOCED (1 << 13) |
Structure was malloc'ed, instead of placed in a return (usually static) buffer
Definition at line 234 of file app_voicemail.c.
Referenced by find_user(), find_user_realtime(), free_user(), and free_vm_users().
| #define VM_ATTACH (1 << 11) |
Attach message to voicemail notifications?
Definition at line 232 of file app_voicemail.c.
Referenced by apply_option(), forward_message(), load_config(), manager_list_voicemail_users(), notify_new_message(), and sendmail().
| #define VM_DELETE (1 << 12) |
Delete message after sending notification
Definition at line 233 of file app_voicemail.c.
Referenced by apply_option(), 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 231 of file app_voicemail.c.
Referenced by forward_message(), and load_config().
| #define VM_ENVELOPE (1 << 4) |
Play the envelope information (who-from, time received, etc.)
Definition at line 225 of file app_voicemail.c.
Referenced by apply_option(), load_config(), manager_list_voicemail_users(), and play_message().
| #define VM_FORCEGREET (1 << 8) |
Have new users record their greetings
Definition at line 229 of file app_voicemail.c.
Referenced by apply_option(), load_config(), vm_execmain(), and vm_newuser().
| #define VM_FORCENAME (1 << 7) |
Have new users record their name
Definition at line 228 of file app_voicemail.c.
Referenced by apply_option(), load_config(), vm_execmain(), and vm_newuser().
| #define VM_FWDURGAUTO (1 << 18) |
Autoset of Urgent flag on forwarded Urgent messages set globally
Definition at line 239 of file app_voicemail.c.
Referenced by forward_message(), and load_config().
| #define VM_MESSAGEWRAP (1 << 17) |
Wrap around from the last message to the first, and vice-versa
Definition at line 238 of file app_voicemail.c.
Referenced by apply_option(), load_config(), vm_execmain(), and vm_instructions_en().
| #define VM_MOVEHEARD (1 << 16) |
Move a "heard" message to Old after listening to it
Definition at line 237 of file app_voicemail.c.
Referenced by apply_option(), close_mailbox(), and load_config().
| #define VM_OPERATOR (1 << 1) |
Allow 0 to be pressed to go to 'o' extension
Definition at line 222 of file app_voicemail.c.
Referenced by apply_option(), leave_voicemail(), load_config(), 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 230 of file app_voicemail.c.
Referenced by 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 221 of file app_voicemail.c.
Referenced by apply_option(), load_config(), manager_list_voicemail_users(), and play_record_review().
| #define VM_SAYCID (1 << 2) |
Repeat the CallerID info during envelope playback
Definition at line 223 of file app_voicemail.c.
Referenced by apply_option(), load_config(), manager_list_voicemail_users(), and play_message().
| #define VM_SAYDURATION (1 << 5) |
Play the length of the message during envelope playback
Definition at line 226 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and play_message().
| #define VM_SEARCH (1 << 14) |
Search all contexts for a matching mailbox
Definition at line 235 of file app_voicemail.c.
Referenced by find_or_create(), find_user(), find_user_realtime(), and load_config().
| #define VM_SKIPAFTERCMD (1 << 6) |
After deletion, assume caller wants to go to the next message
Definition at line 227 of file app_voicemail.c.
Referenced by load_config(), and vm_execmain().
| #define VM_SVMAIL (1 << 3) |
Allow the user to compose a new VM from within VoicemailMain
Definition at line 224 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and vm_execmain().
| #define VM_TEMPGREETWARN (1 << 15) |
Remind user tempgreeting is set
Definition at line 236 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and vm_intro().
| #define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 418 of file app_voicemail.c.
| #define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 190 of file app_voicemail.c.
| #define VOICEMAIL_DIR_MODE 0777 |
Definition at line 186 of file app_voicemail.c.
| #define VOICEMAIL_FILE_MODE 0666 |
Definition at line 187 of file app_voicemail.c.
Referenced by add_email_attachment(), copy(), leave_voicemail(), and vm_mkftemp().
| anonymous enum |
Definition at line 243 of file app_voicemail.c.
00243 { 00244 NEW_FOLDER, 00245 OLD_FOLDER, 00246 WORK_FOLDER, 00247 FAMILY_FOLDER, 00248 FRIENDS_FOLDER, 00249 GREETINGS_FOLDER 00250 } vm_box;
| anonymous enum |
| 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 252 of file app_voicemail.c.
00252 { 00253 OPT_SILENT = (1 << 0), 00254 OPT_BUSY_GREETING = (1 << 1), 00255 OPT_UNAVAIL_GREETING = (1 << 2), 00256 OPT_RECORDGAIN = (1 << 3), 00257 OPT_PREPEND_MAILBOX = (1 << 4), 00258 OPT_AUTOPLAY = (1 << 6), 00259 OPT_DTMFEXIT = (1 << 7), 00260 OPT_MESSAGE_Urgent = (1 << 8), 00261 OPT_MESSAGE_PRIORITY = (1 << 9) 00262 } vm_option_flags;
| anonymous enum |
Definition at line 264 of file app_voicemail.c.
00264 { 00265 OPT_ARG_RECORDGAIN = 0, 00266 OPT_ARG_PLAYFOLDER = 1, 00267 OPT_ARG_DTMFEXIT = 2, 00268 /* This *must* be the last value in this enum! */ 00269 OPT_ARG_ARRAY_SIZE = 3, 00270 } vm_option_args;
| static int __has_voicemail | ( | const char * | context, | |
| const char * | mailbox, | |||
| const char * | folder, | |||
| int | shortcircuit | |||
| ) | [static] |
Definition at line 4754 of file app_voicemail.c.
References ast_strlen_zero().
Referenced by has_voicemail(), inboxcount2(), and messagecount().
04755 { 04756 DIR *dir; 04757 struct dirent *de; 04758 char fn[256]; 04759 int ret = 0; 04760 04761 /* If no mailbox, return immediately */ 04762 if (ast_strlen_zero(mailbox)) 04763 return 0; 04764 04765 if (ast_strlen_zero(folder)) 04766 folder = "INBOX"; 04767 if (ast_strlen_zero(context)) 04768 context = "default"; 04769 04770 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 04771 04772 if (!(dir = opendir(fn))) 04773 return 0; 04774 04775 while ((de = readdir(dir))) { 04776 if (!strncasecmp(de->d_name, "msg", 3)) { 04777 if (shortcircuit) { 04778 ret = 1; 04779 break; 04780 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 04781 if (shortcircuit) return 1; 04782 ret++; 04783 } 04784 } 04785 } 04786 04787 closedir(dir); 04788 04789 /* If we are checking INBOX, we should check Urgent as well */ 04790 if (strcmp(folder, "INBOX") == 0) { 04791 return (ret + __has_voicemail(context, mailbox, "Urgent", shortcircuit)); 04792 } else { 04793 return ret; 04794 } 04795 }
| static void __reg_module | ( | void | ) | [static] |
Definition at line 11595 of file app_voicemail.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 11595 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 9750 of file app_voicemail.c.
References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_strlen_zero(), find_user(), LOG_ERROR, and mbox().
09751 { 09752 struct ast_vm_user svm; 09753 AST_DECLARE_APP_ARGS(arg, 09754 AST_APP_ARG(mbox); 09755 AST_APP_ARG(context); 09756 ); 09757 09758 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 09759 09760 if (ast_strlen_zero(arg.mbox)) { 09761 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 09762 return -1; 09763 } 09764 09765 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 09766 return 0; 09767 }
| 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 4245 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().
04246 { 04247 char tmpdir[256], newtmp[256]; 04248 char fname[256]; 04249 char tmpcmd[256]; 04250 int tmpfd = -1; 04251 04252 /* Eww. We want formats to tell us their own MIME type */ 04253 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04254 04255 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04256 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04257 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04258 tmpfd = mkstemp(newtmp); 04259 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04260 ast_debug(3, "newtmp: %s\n", newtmp); 04261 if (tmpfd > -1) { 04262 int soxstatus; 04263 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04264 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04265 attach = newtmp; 04266 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04267 } else { 04268 ast_log(LOG_WARNING, "Sox failed to reencode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04269 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04270 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04271 } 04272 } 04273 } 04274 fprintf(p, "--%s" ENDL, bound); 04275 if (msgnum > -1) 04276 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04277 else 04278 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04279 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04280 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04281 if (msgnum > -1) 04282 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04283 else 04284 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04285 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04286 base_encode(fname, p); 04287 if (last) 04288 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04289 if (tmpfd > -1) { 04290 unlink(fname); 04291 close(tmpfd); 04292 unlink(newtmp); 04293 } 04294 return 0; 04295 }
| static void adsi_begin | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 5675 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().
05676 { 05677 int x; 05678 if (!ast_adsi_available(chan)) 05679 return; 05680 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 05681 if (x < 0) 05682 return; 05683 if (!x) { 05684 if (adsi_load_vmail(chan, useadsi)) { 05685 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 05686 return; 05687 } 05688 } else 05689 *useadsi = 1; 05690 }
| static void adsi_delete | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 5864 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().
05865 { 05866 int bytes=0; 05867 unsigned char buf[256]; 05868 unsigned char keys[8]; 05869 05870 int x; 05871 05872 if (!ast_adsi_available(chan)) 05873 return; 05874 05875 /* New meaning for keys */ 05876 for (x=0;x<5;x++) 05877 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 05878 05879 keys[6] = 0x0; 05880 keys[7] = 0x0; 05881 05882 if (!vms->curmsg) { 05883 /* No prev key, provide "Folder" instead */ 05884 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05885 } 05886 if (vms->curmsg >= vms->lastmsg) { 05887 /* If last message ... */ 05888 if (vms->curmsg) { 05889 /* but not only message, provide "Folder" instead */ 05890 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05891 } else { 05892 /* Otherwise if only message, leave blank */ 05893 keys[3] = 1; 05894 } 05895 } 05896 05897 /* If deleted, show "undeleted" */ 05898 if (vms->deleted[vms->curmsg]) 05899 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 05900 05901 /* Except "Exit" */ 05902 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 05903 bytes += ast_adsi_set_keys(buf + bytes, keys); 05904 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05905 05906 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05907 }
| static void adsi_folders | ( | struct ast_channel * | chan, | |
| int | start, | |||
| char * | label | |||
| ) | [static] |
Definition at line 5740 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().
05741 { 05742 unsigned char buf[256]; 05743 int bytes=0; 05744 unsigned char keys[8]; 05745 int x,y; 05746 05747 if (!ast_adsi_available(chan)) 05748 return; 05749 05750 for (x=0;x<5;x++) { 05751 y = ADSI_KEY_APPS + 12 + start + x; 05752 if (y > ADSI_KEY_APPS + 12 + 4) 05753 y = 0; 05754 keys[x] = ADSI_KEY_SKT | y; 05755 } 05756 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 05757 keys[6] = 0; 05758 keys[7] = 0; 05759 05760 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 05761 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 05762 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05763 bytes += ast_adsi_set_keys(buf + bytes, keys); 05764 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05765 05766 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05767 }
| static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6012 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().
06013 { 06014 unsigned char buf[256]; 06015 int bytes=0; 06016 06017 if (!ast_adsi_available(chan)) 06018 return; 06019 bytes += adsi_logo(buf + bytes); 06020 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06021 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06022 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06023 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06024 06025 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06026 }
| static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 5546 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, mbox(), and num.
Referenced by adsi_begin().
05547 { 05548 unsigned char buf[256]; 05549 int bytes=0; 05550 int x; 05551 char num[5]; 05552 05553 *useadsi = 0; 05554 bytes += ast_adsi_data_mode(buf + bytes); 05555 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05556 05557 bytes = 0; 05558 bytes += adsi_logo(buf); 05559 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 05560 #ifdef DISPLAY 05561 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 05562 #endif 05563 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05564 bytes += ast_adsi_data_mode(buf + bytes); 05565 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05566 05567 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 05568 bytes = 0; 05569 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 05570 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 05571 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05572 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05573 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05574 return 0; 05575 } 05576 05577 #ifdef DISPLAY 05578 /* Add a dot */ 05579 bytes = 0; 05580 bytes += ast_adsi_logo(buf); 05581 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 05582 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 05583 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05584 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05585 #endif 05586 bytes = 0; 05587 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 05588 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 05589 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 05590 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 05591 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 05592 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 05593 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05594 05595 #ifdef DISPLAY 05596 /* Add another dot */ 05597 bytes = 0; 05598 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 05599 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05600 05601 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05602 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05603 #endif 05604 05605 bytes = 0; 05606 /* These buttons we load but don't use yet */ 05607 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 05608 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 05609 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 05610 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 05611 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 05612 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 05613 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05614 05615 #ifdef DISPLAY 05616 /* Add another dot */ 05617 bytes = 0; 05618 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 05619 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05620 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05621 #endif 05622 05623 bytes = 0; 05624 for (x=0;x<5;x++) { 05625 snprintf(num, sizeof(num), "%d", x); 05626 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1); 05627 } 05628 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 05629 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05630 05631 #ifdef DISPLAY 05632 /* Add another dot */ 05633 bytes = 0; 05634 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 05635 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05636 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05637 #endif 05638 05639 if (ast_adsi_end_download(chan)) { 05640 bytes = 0; 05641 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 05642 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 05643 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05644 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05645 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05646 return 0; 05647 } 05648 bytes = 0; 05649 bytes += ast_adsi_download_disconnect(buf + bytes); 05650 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05651 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05652 05653 ast_debug(1, "Done downloading scripts...\n"); 05654 05655 #ifdef DISPLAY 05656 /* Add last dot */ 05657 bytes = 0; 05658 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 05659 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05660 #endif 05661 ast_debug(1, "Restarting session...\n"); 05662 05663 bytes = 0; 05664 /* Load the session now */ 05665 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 05666 *useadsi = 1; 05667 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 05668 } else 05669 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 05670 05671 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05672 return 0; 05673 }
| static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5692 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().
05693 { 05694 unsigned char buf[256]; 05695 int bytes=0; 05696 unsigned char keys[8]; 05697 int x; 05698 if (!ast_adsi_available(chan)) 05699 return; 05700 05701 for (x=0;x<8;x++) 05702 keys[x] = 0; 05703 /* Set one key for next */ 05704 keys[3] = ADSI_KEY_APPS + 3; 05705 05706 bytes += adsi_logo(buf + bytes); 05707 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 05708 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 05709 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05710 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 05711 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 05712 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 05713 bytes += ast_adsi_set_keys(buf + bytes, keys); 05714 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05715 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05716 }
| static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 5538 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().
05539 { 05540 int bytes = 0; 05541 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 05542 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 05543 return bytes; 05544 }
| static void adsi_message | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 5769 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(), vm_state::curbox, vm_state::curmsg, vm_state::deleted, vm_state::fn, vm_state::lastmsg, num, and strsep().
Referenced by play_message(), and vm_execmain().
05770 { 05771 int bytes=0; 05772 unsigned char buf[256]; 05773 char buf1[256], buf2[256]; 05774 char fn2[PATH_MAX]; 05775 05776 char cid[256]=""; 05777 char *val; 05778 char *name, *num; 05779 char datetime[21]=""; 05780 FILE *f; 05781 05782 unsigned char keys[8]; 05783 05784 int x; 05785 05786 if (!ast_adsi_available(chan)) 05787 return; 05788 05789 /* Retrieve important info */ 05790 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 05791 f = fopen(fn2, "r"); 05792 if (f) { 05793 while (!feof(f)) { 05794 if (!fgets((char *)buf, sizeof(buf), f)) { 05795 continue; 05796 } 05797 if (!feof(f)) { 05798 char *stringp=NULL; 05799 stringp = (char *)buf; 05800 strsep(&stringp, "="); 05801 val = strsep(&stringp, "="); 05802 if (!ast_strlen_zero(val)) { 05803 if (!strcmp((char *)buf, "callerid")) 05804 ast_copy_string(cid, val, sizeof(cid)); 05805 if (!strcmp((char *)buf, "origdate")) 05806 ast_copy_string(datetime, val, sizeof(datetime)); 05807 } 05808 } 05809 } 05810 fclose(f); 05811 } 05812 /* New meaning for keys */ 05813 for (x=0;x<5;x++) 05814 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 05815 keys[6] = 0x0; 05816 keys[7] = 0x0; 05817 05818 if (!vms->curmsg) { 05819 /* No prev key, provide "Folder" instead */ 05820 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05821 } 05822 if (vms->curmsg >= vms->lastmsg) { 05823 /* If last message ... */ 05824 if (vms->curmsg) { 05825 /* but not only message, provide "Folder" instead */ 05826 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05827 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05828 05829 } else { 05830 /* Otherwise if only message, leave blank */ 05831 keys[3] = 1; 05832 } 05833 } 05834 05835 if (!ast_strlen_zero(cid)) { 05836 ast_callerid_parse(cid, &name, &num); 05837 if (!name) 05838 name = num; 05839 } else 05840 name = "Unknown Caller"; 05841 05842 /* If deleted, show "undeleted" */ 05843 05844 if (vms->deleted[vms->curmsg]) 05845 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 05846 05847 /* Except "Exit" */ 05848 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 05849 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 05850 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 05851 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 05852 05853 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 05854 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 05855 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 05856 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 05857 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05858 bytes += ast_adsi_set_keys(buf + bytes, keys); 05859 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05860 05861 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05862 }
| static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5718 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().
05719 { 05720 unsigned char buf[256]; 05721 int bytes=0; 05722 unsigned char keys[8]; 05723 int x; 05724 if (!ast_adsi_available(chan)) 05725 return; 05726 05727 for (x=0;x<8;x++) 05728 keys[x] = 0; 05729 /* Set one key for next */ 05730 keys[3] = ADSI_KEY_APPS + 3; 05731 05732 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05733 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 05734 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 05735 bytes += ast_adsi_set_keys(buf + bytes, keys); 05736 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05737 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05738 }
| static void adsi_status | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 5909 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, ast_adsi_voice_mode, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_execmain().
05910 { 05911 unsigned char buf[256] = ""; 05912 char buf1[256] = "", buf2[256] = ""; 05913 int bytes=0; 05914 unsigned char keys[8]; 05915 int x; 05916 05917 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 05918 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 05919 if (!ast_adsi_available(chan)) 05920 return; 05921 if (vms->newmessages) { 05922 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 05923 if (vms->oldmessages) { 05924 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 05925 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 05926 } else { 05927 snprintf(buf2, sizeof(buf2), "%s.", newm); 05928 } 05929 } else if (vms->oldmessages) { 05930 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 05931 snprintf(buf2, sizeof(buf2), "%s.", oldm); 05932 } else { 05933 strcpy(buf1, "You have no messages."); 05934 buf2[0] = ' '; 05935 buf2[1] = '\0'; 05936 } 05937 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 05938 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 05939 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05940 05941 for (x=0;x<6;x++) 05942 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 05943 keys[6] = 0; 05944 keys[7] = 0; 05945 05946 /* Don't let them listen if there are none */ 05947 if (vms->lastmsg < 0) 05948 keys[0] = 1; 05949 bytes += ast_adsi_set_keys(buf + bytes, keys); 05950 05951 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05952 05953 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05954 }
| static void adsi_status2 | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 5956 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, ast_adsi_voice_mode, vm_state::curbox, and vm_state::lastmsg.
Referenced by vm_execmain().
05957 { 05958 unsigned char buf[256] = ""; 05959 char buf1[256] = "", buf2[256] = ""; 05960 int bytes=0; 05961 unsigned char keys[8]; 05962 int x; 05963 05964 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 05965 05966 if (!ast_adsi_available(chan)) 05967 return; 05968 05969 /* Original command keys */ 05970 for (x=0;x<6;x++) 05971 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 05972 05973 keys[6] = 0; 05974 keys[7] = 0; 05975 05976 if ((vms->lastmsg + 1) < 1) 05977 keys[0] = 0; 05978 05979 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 05980 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 05981 05982 if (vms->lastmsg + 1) 05983 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 05984 else 05985 strcpy(buf2, "no messages."); 05986 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 05987 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 05988 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 05989 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05990 bytes += ast_adsi_set_keys(buf + bytes, keys); 05991 05992 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05993 05994 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05995 05996 }
| 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 11171 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_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), num, play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, and wait_file().
Referenced by vm_execmain().
11172 { 11173 int res = 0; 11174 char filename[PATH_MAX]; 11175 struct ast_config *msg_cfg = NULL; 11176 const char *origtime, *context; 11177 char *name, *num; 11178 int retries = 0; 11179 char *cid; 11180 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 11181 11182 vms->starting = 0; 11183 11184 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 11185 11186 /* Retrieve info from VM attribute file */ 11187 snprintf(filename,sizeof(filename), "%s.txt", vms->fn); 11188 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 11189 msg_cfg = ast_config_load(filename, config_flags); 11190 DISPOSE(vms->curdir, vms->curmsg); 11191 if (!msg_cfg) { 11192 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 11193 return 0; 11194 } 11195 11196 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 11197 ast_config_destroy(msg_cfg); 11198 return 0; 11199 } 11200 11201 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 11202 11203 context = ast_variable_retrieve(msg_cfg, "message", "context"); 11204 if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */ 11205 context = ast_variable_retrieve(msg_cfg, "message","macrocontext"); 11206 switch (option) { 11207 case 3: /* Play message envelope */ 11208 if (!res) 11209 res = play_message_datetime(chan, vmu, origtime, filename); 11210 if (!res) 11211 res = play_message_callerid(chan, vms, cid, context, 0); 11212 11213 res = 't'; 11214 break; 11215 11216 case 2: /* Call back */ 11217 11218 if (ast_strlen_zero(cid)) 11219 break; 11220 11221 ast_callerid_parse(cid, &name, &num); 11222 while ((res > -1) && (res != 't')) { 11223 switch (res) { 11224 case '1': 11225 if (num) { 11226 /* Dial the CID number */ 11227 res = dialout(chan, vmu, num, vmu->callback); 11228 if (res) { 11229 ast_config_destroy(msg_cfg); 11230 return 9; 11231 } 11232 } else { 11233 res = '2'; 11234 } 11235 break; 11236 11237 case '2': 11238 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 11239 if (!ast_strlen_zero(vmu->dialout)) { 11240 res = dialout(chan, vmu, NULL, vmu->dialout); 11241 if (res) { 11242 ast_config_destroy(msg_cfg); 11243 return 9; 11244 } 11245 } else { 11246 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 11247 res = ast_play_and_wait(chan, "vm-sorry"); 11248 } 11249 ast_config_destroy(msg_cfg); 11250 return res; 11251 case '*': 11252 res = 't'; 11253 break; 11254 case '3': 11255 case '4': 11256 case '5': 11257 case '6': 11258 case '7': 11259 case '8': 11260 case '9': 11261 case '0': 11262 11263 res = ast_play_and_wait(chan, "vm-sorry"); 11264 retries++; 11265 break; 11266 default: 11267 if (num) { 11268 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 11269 res = ast_play_and_wait(chan, "vm-num-i-have"); 11270 if (!res) 11271 res = play_message_callerid(chan, vms, num, vmu->context, 1); 11272 if (!res) 11273 res = ast_play_and_wait(chan, "vm-tocallnum"); 11274 /* Only prompt for a caller-specified number if there is a dialout context specified */ 11275 if (!ast_strlen_zero(vmu->dialout)) { 11276 if (!res) 11277 res = ast_play_and_wait(chan, "vm-calldiffnum"); 11278 } 11279 } else { 11280 res = ast_play_and_wait(chan, "vm-nonumber"); 11281 if (!ast_strlen_zero(vmu->dialout)) { 11282 if (!res) 11283 res = ast_play_and_wait(chan, "vm-toenternumber"); 11284 } 11285 } 11286 if (!res) 11287 res = ast_play_and_wait(chan, "vm-star-cancel"); 11288 if (!res) 11289 res = ast_waitfordigit(chan, 6000); 11290 if (!res) { 11291 retries++; 11292 if (retries > 3) 11293 res = 't'; 11294 } 11295 break; 11296 11297 } 11298 if (res == 't') 11299 res = 0; 11300 else if (res == '*') 11301 res = -1; 11302 } 11303 break; 11304 11305 case 1: /* Reply */ 11306 /* Send reply directly to sender */ 11307 if (ast_strlen_zero(cid)) 11308 break; 11309 11310 ast_callerid_parse(cid, &name, &num); 11311 if (!num) { 11312 ast_verb(3, "No CID number available, no reply sent\n"); 11313 if (!res) 11314 res = ast_play_and_wait(chan, "vm-nonumber"); 11315 ast_config_destroy(msg_cfg); 11316 return res; 11317 } else { 11318 struct ast_vm_user vmu2; 11319 if (find_user(&vmu2, vmu->context, num)) { 11320 struct leave_vm_options leave_options; 11321 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 11322 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 11323 11324 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 11325 11326 memset(&leave_options, 0, sizeof(leave_options)); 11327 leave_options.record_gain = record_gain; 11328 res = leave_voicemail(chan, mailbox, &leave_options); 11329 if (!res) 11330 res = 't'; 11331 ast_config_destroy(msg_cfg); 11332 return res; 11333 } else { 11334 /* Sender has no mailbox, can't reply */ 11335 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 11336 ast_play_and_wait(chan, "vm-nobox"); 11337 res = 't'; 11338 ast_config_destroy(msg_cfg); 11339 return res; 11340 } 11341 } 11342 res = 0; 11343 11344 break; 11345 } 11346 11347 #ifndef IMAP_STORAGE 11348 ast_config_destroy(msg_cfg); 11349 11350 if (!res) { 11351 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 11352 vms->heard[msg] = 1; 11353 res = wait_file(chan, vms, vms->fn); 11354 } 11355 #endif 11356 return res; 11357 }
| static int append_mailbox | ( | const char * | context, | |
| const char * | box, | |||
| const char * | data | |||
| ) | [static] |
Definition at line 9670 of file app_voicemail.c.
References apply_options(), ast_copy_string(), ast_strdupa, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, inboxcount2(), ast_vm_user::pager, ast_vm_user::password, populate_defaults(), queue_mwi_event(), s, and strsep().
Referenced by load_config().
09671 { 09672 /* Assumes lock is already held */ 09673 char *tmp; 09674 char *stringp; 09675 char *s; 09676 struct ast_vm_user *vmu; 09677 char *mailbox_full; 09678 int new = 0, old = 0, urgent = 0; 09679 09680 tmp = ast_strdupa(data); 09681 09682 if (!(vmu = find_or_create(context, box))) 09683 return -1; 09684 09685 populate_defaults(vmu); 09686 09687 stringp = tmp; 09688 if ((s = strsep(&stringp, ","))) 09689 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 09690 if (stringp && (s = strsep(&stringp, ","))) 09691 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 09692 if (stringp && (s = strsep(&stringp, ","))) 09693 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 09694 if (stringp && (s = strsep(&stringp, ","))) 09695 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 09696 if (stringp && (s = strsep(&stringp, ","))) 09697 apply_options(vmu, s); 09698 09699 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 09700 strcpy(mailbox_full, box); 09701 strcat(mailbox_full, "@"); 09702 strcat(mailbox_full, context); 09703 09704 inboxcount2(mailbox_full, &urgent, &new, &old); 09705 queue_mwi_event(mailbox_full, urgent, new, old); 09706 09707 return 0; 09708 }
| static void apply_option | ( | struct ast_vm_user * | vmu, | |
| const char * | var, | |||
| const char * | value | |||
| ) | [static] |
Sets a a specific property value.
| vmu | The voicemail user object to work with. | |
| var | The name of the property to be set. | |
| value | The value to be set to the property. |
The property name must be one of the understood properties. See the source for details.
Definition at line 785 of file app_voicemail.c.
References apply_options(), ast_copy_string(), ast_log(), AST_LOG_WARNING, ast_set2_flag, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::exit, ast_vm_user::language, ast_vm_user::maxdeletedmsg, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::maxsecs, ast_vm_user::saydurationm, ast_vm_user::serveremail, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by apply_options(), and apply_options_full().
00786 { 00787 int x; 00788 if (!strcasecmp(var, "attach")) { 00789 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 00790 } else if (!strcasecmp(var, "attachfmt")) { 00791 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 00792 } else if (!strcasecmp(var, "serveremail")) { 00793 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 00794 } else if (!strcasecmp(var, "language")) { 00795 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 00796 } else if (!strcasecmp(var, "tz")) { 00797 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 00798 #ifdef IMAP_STORAGE 00799 } else if (!strcasecmp(var, "imapuser")) { 00800 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 00801 vmu->imapversion = imapversion; 00802 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 00803 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 00804 vmu->imapversion = imapversion; 00805 } else if (!strcasecmp(var, "imapvmshareid")) { 00806 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 00807 vmu->imapversion = imapversion; 00808 #endif 00809 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 00810 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 00811 } else if (!strcasecmp(var, "saycid")){ 00812 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 00813 } else if (!strcasecmp(var,"sendvoicemail")){ 00814 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 00815 } else if (!strcasecmp(var, "review")){ 00816 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 00817 } else if (!strcasecmp(var, "tempgreetwarn")){ 00818 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 00819 } else if (!strcasecmp(var, "messagewrap")){ 00820 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 00821 } else if (!strcasecmp(var, "operator")) { 00822 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 00823 } else if (!strcasecmp(var, "envelope")){ 00824 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 00825 } else if (!strcasecmp(var, "moveheard")){ 00826 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 00827 } else if (!strcasecmp(var, "sayduration")){ 00828 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 00829 } else if (!strcasecmp(var, "saydurationm")){ 00830 if (sscanf(value, "%30d", &x) == 1) { 00831 vmu->saydurationm = x; 00832 } else { 00833 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 00834 } 00835 } else if (!strcasecmp(var, "forcename")){ 00836 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 00837 } else if (!strcasecmp(var, "forcegreetings")){ 00838 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 00839 } else if (!strcasecmp(var, "callback")) { 00840 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 00841 } else if (!strcasecmp(var, "dialout")) { 00842 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 00843 } else if (!strcasecmp(var, "exitcontext")) { 00844 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 00845 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 00846 vmu->maxsecs = atoi(value); 00847 if (vmu->maxsecs <= 0) { 00848 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 00849 vmu->maxsecs = vmmaxsecs; 00850 } else { 00851 vmu->maxsecs = atoi(value); 00852 } 00853 if (!strcasecmp(var, "maxmessage")) 00854 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 00855 } else if (!strcasecmp(var, "maxmsg")) { 00856 vmu->maxmsg = atoi(value); 00857 if (vmu->maxmsg <= 0) { 00858 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 00859 vmu->maxmsg = MAXMSG; 00860 } else if (vmu->maxmsg > MAXMSGLIMIT) { 00861 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 00862 vmu->maxmsg = MAXMSGLIMIT; 00863 } 00864 } else if (!strcasecmp(var, "backupdeleted")) { 00865 if (sscanf(value, "%30d", &x) == 1) 00866 vmu->maxdeletedmsg = x; 00867 else if (ast_true(value)) 00868 vmu->maxdeletedmsg = MAXMSG; 00869 else 00870 vmu->maxdeletedmsg = 0; 00871 00872 if (vmu->maxdeletedmsg < 0) { 00873 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 00874 vmu->maxdeletedmsg = MAXMSG; 00875 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 00876 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 00877 vmu->maxdeletedmsg = MAXMSGLIMIT; 00878 } 00879 } else if (!strcasecmp(var, "volgain")) { 00880 sscanf(value, "%30lf", &vmu->volgain); 00881 } else if (!strcasecmp(var, "options")) { 00882 apply_options(vmu, value); 00883 } 00884 }
| static void apply_options | ( | struct ast_vm_user * | vmu, | |
| const char * | options | |||
| ) | [static] |
Destructively Parse options and apply.
Definition at line 998 of file app_voicemail.c.
References apply_option(), ast_strdupa, s, strsep(), and var.
Referenced by append_mailbox(), and apply_option().
00999 { 01000 char *stringp; 01001 char *s; 01002 char *var, *value; 01003 stringp = ast_strdupa(options); 01004 while ((s = strsep(&stringp, "|"))) { 01005 value = s; 01006 if ((var = strsep(&value, "=")) && value) { 01007 apply_option(vmu, var, value); 01008 } 01009 } 01010 }
| 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 1017 of file app_voicemail.c.
References apply_option(), ast_copy_string(), ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, ast_vm_user::fullname, ast_variable::name, ast_variable::next, ast_vm_user::pager, ast_vm_user::password, ast_vm_user::uniqueid, and ast_variable::value.
Referenced by find_user_realtime(), and load_config().
01018 { 01019 struct ast_variable *tmp; 01020 tmp = var; 01021 while (tmp) { 01022 if (!strcasecmp(tmp->name, "vmsecret")) { 01023 ast_copy_string(retval->password, tmp->value, sizeof(retval->password)); 01024 } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */ 01025 if (ast_strlen_zero(retval->password)) 01026 ast_copy_string(retval->password, tmp->value, sizeof(retval->password)); 01027 } else if (!strcasecmp(tmp->name, "uniqueid")) { 01028 ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid)); 01029 } else if (!strcasecmp(tmp->name, "pager")) { 01030 ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager)); 01031 } else if (!strcasecmp(tmp->name, "email")) { 01032 ast_copy_string(retval->email, tmp->value, sizeof(retval->email)); 01033 } else if (!strcasecmp(tmp->name, "fullname")) { 01034 ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname)); 01035 } else if (!strcasecmp(tmp->name, "context")) { 01036 ast_copy_string(retval->context, tmp->value, sizeof(retval->context)); 01037 #ifdef IMAP_STORAGE 01038 } else if (!strcasecmp(tmp->name, "imapuser")) { 01039 ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser)); 01040 retval->imapversion = imapversion; 01041 } else if (!strcasecmp(tmp->name, "imappassword") || !strcasecmp(tmp->name, "imapsecret")) { 01042 ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword)); 01043 retval->imapversion = imapversion; 01044 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01045 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01046 retval->imapversion = imapversion; 01047 #endif 01048 } else 01049 apply_option(retval, tmp->name, tmp->value); 01050 tmp = tmp->next; 01051 } 01052 }
| static int base_encode | ( | char * | filename, | |
| FILE * | so | |||
| ) | [static] |
Performs a base 64 encode algorithm on the contents of a File.
| filename | The path to the file to be encoded. Must be readable, file is opened in read mode. | |
| so | A FILE handle to the output file to receive the base 64 encoded contents of the input file, identified by filename. |
TODO: shouldn't this (and the above 3 support functions) be put into some kind of external utility location, such as funcs/func_base64.c ?
Definition at line 3733 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, BASEMAXINLINE, eol, errno, inchar(), baseio::iocp, and ochar().
Referenced by add_email_attachment().
03734 { 03735 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 03736 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 03737 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 03738 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 03739 int i,hiteof= 0; 03740 FILE *fi; 03741 struct baseio bio; 03742 03743 memset(&bio, 0, sizeof(bio)); 03744 bio.iocp = BASEMAXINLINE; 03745 03746 if (!(fi = fopen(filename, "rb"))) { 03747 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 03748 return -1; 03749 } 03750 03751 while (!hiteof){ 03752 unsigned char igroup[3], ogroup[4]; 03753 int c,n; 03754 03755 igroup[0]= igroup[1]= igroup[2]= 0; 03756 03757 for (n= 0;n<3;n++) { 03758 if ((c = inchar(&bio, fi)) == EOF) { 03759 hiteof= 1; 03760 break; 03761 } 03762 03763 igroup[n]= (unsigned char)c; 03764 } 03765 03766 if (n> 0) { 03767 ogroup[0]= dtable[igroup[0]>>2]; 03768 ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)]; 03769 ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)]; 03770 ogroup[3]= dtable[igroup[2]&0x3F]; 03771 03772 if (n<3) { 03773 ogroup[3]= '='; 03774 03775 if (n<2) 03776 ogroup[2]= '='; 03777 } 03778 03779 for (i= 0;i<4;i++) 03780 ochar(&bio, ogroup[i], so); 03781 } 03782 } 03783 03784 fclose(fi); 03785 03786 if (fputs(eol,so)==EOF) 03787 return 0; 03788 03789 return 1; 03790 }
| static int change_password_realtime | ( | struct ast_vm_user * | vmu, | |
| const char * | password | |||
| ) | [static] |
Performs a change of the voicemail passowrd in the realtime engine.
| vmu | The voicemail user to change the password for. | |
| password | The new value to be set to the password for this user. |
This only works if there is a realtime engine configured. This is called from the (top level) vm_change_password.
Definition at line 977 of file app_voicemail.c.
References ast_copy_string(), ast_realtime_require_field(), ast_strlen_zero(), ast_update_realtime(), ast_vm_user::password, RQ_CHAR, SENTINEL, and ast_vm_user::uniqueid.
Referenced by vm_change_password().
00978 { 00979 int res = -1; 00980 if (!strcmp(vmu->password, password)) { 00981 /* No change (but an update would return 0 rows updated, so we opt out here) */ 00982 res = 0; 00983 } else if (!ast_strlen_zero(vmu->uniqueid)) { 00984 if (strlen(password) > 10) { 00985 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 00986 } 00987 if (ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, SENTINEL) > 0) { 00988 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 00989 res = 0; 00990 } 00991 } 00992 return res; 00993 }
| 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 3898 of file app_voicemail.c.
Referenced by make_email_file().
| 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 939 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_DEBUG, AST_LOG_NOTICE, AST_LOG_WARNING, ast_strlen_zero(), buf, ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and vm_check_password_shell().
Referenced by vm_newuser(), and vm_options().
00940 { 00941 /* check minimum length */ 00942 if (strlen(password) < minpassword) 00943 return 1; 00944 if (!ast_strlen_zero(ext_pass_check_cmd)) { 00945 char cmd[255], buf[255]; 00946 00947 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 00948 00949 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 00950 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 00951 ast_debug(5, "Result: %s\n", buf); 00952 if (!strncasecmp(buf, "VALID", 5)) { 00953 ast_debug(3, "Passed password check: '%s'\n", buf); 00954 return 0; 00955 } else if (!strncasecmp(buf, "FAILURE", 7)) { 00956 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 00957 return 0; 00958 } else { 00959 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 00960 return 1; 00961 } 00962 } 00963 } 00964 return 0; 00965 }
| static int close_mailbox | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu | |||
| ) | [static] |
Definition at line 7064 of file app_voicemail.c.
References ast_check_realtime(), ast_debug, ast_log(), 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, ERROR_LOCK_PATH, EXISTS, vm_state::fn, vm_state::heard, vm_state::lastmsg, ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, RENAME, save_to_folder(), vm_lock_path(), and VM_MOVEHEARD.
Referenced by vm_execmain().
07065 { 07066 int x = 0; 07067 #ifndef IMAP_STORAGE 07068 int res = 0, nummsg; 07069 char fn2[PATH_MAX]; 07070 #endif 07071 07072 if (vms->lastmsg <= -1) 07073 goto done; 07074 07075 vms->curmsg = -1; 07076 #ifndef IMAP_STORAGE 07077 /* Get the deleted messages fixed */ 07078 if (vm_lock_path(vms->curdir)) 07079 return ERROR_LOCK_PATH; 07080 07081 for (x = 0; x < vmu->maxmsg; x++) { 07082 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07083 /* Save this message. It's not in INBOX or hasn't been heard */ 07084 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07085 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 07086 break; 07087 vms->curmsg++; 07088 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 07089 if (strcmp(vms->fn, fn2)) { 07090 RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07091 } 07092 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07093 /* Move to old folder before deleting */ 07094 res = save_to_folder(vmu, vms, x, 1); 07095 if (res == ERROR_LOCK_PATH) { 07096 /* If save failed do not delete the message */ 07097 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 07098 vms->deleted[x] = 0; 07099 vms->heard[x] = 0; 07100 --x; 07101 } 07102 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 07103 /* Move to deleted folder */ 07104 res = save_to_folder(vmu, vms, x, 10); 07105 if (res == ERROR_LOCK_PATH) { 07106 /* If save failed do not delete the message */ 07107 vms->deleted[x] = 0; 07108 vms->heard[x] = 0; 07109 --x; 07110 } 07111 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 07112 /* If realtime storage enabled - we should explicitly delete this message, 07113 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 07114 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07115 if (EXISTS(vms->curdir, x, vms->fn, NULL)) 07116 DELETE(vms->curdir, x, vms->fn, vmu); 07117 } 07118 } 07119 07120 /* Delete ALL remaining messages */ 07121 nummsg = x - 1; 07122 for (x = vms->curmsg + 1; x <= nummsg; x++) { 07123 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07124 if (EXISTS(vms->curdir, x, vms->fn, NULL)) 07125 DELETE(vms->curdir, x, vms->fn, vmu); 07126 } 07127 ast_unlock_path(vms->curdir); 07128 #else 07129 if (vms->deleted) { 07130 for (x=0;x < vmu->maxmsg;x++) { 07131 if (vms->deleted[x]) { 07132 ast_debug(3,"IMAP delete of %d\n",x); 07133 DELETE(vms->curdir, x, vms->fn, vmu); 07134 } 07135 } 07136 } 07137 #endif 07138 07139 done: 07140 if (vms->deleted) 07141 memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 07142 if (vms->heard) 07143 memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 07144 07145 return 0; 07146 }
| static char* complete_voicemail_show_users | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 9854 of file app_voicemail.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
09855 { 09856 int which = 0; 09857 int wordlen; 09858 struct ast_vm_user *vmu; 09859 const char *context = ""; 09860 09861 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 09862 if (pos > 4) 09863 return NULL; 09864 if (pos == 3) 09865 return (state == 0) ? ast_strdup("for") : NULL; 09866 wordlen = strlen(word); 09867 AST_LIST_TRAVERSE(&users, vmu, list) { 09868 if (!strncasecmp(word, vmu->context, wordlen)) { 09869 if (context && strcmp(context, vmu->context) && ++which > state) 09870 return ast_strdup(vmu->context); 09871 /* ignore repeated contexts ? */ 09872 context = vmu->context; 09873 } 09874 } 09875 return NULL; 09876 }
| static int copy | ( | char * | infile, | |
| char * | outfile | |||
| ) | [static] |
Utility function to copy a file.
| infile | The path to the file to be copied. The file must be readable, it is opened in read only mode. | |
| outfile | The path for which to copy the file to. The directory permissions must allow the creation (or truncation) of the file, and allow for opening the file in write only mode. |
When the compiler option HARDLINK_WHEN_POSSIBLE is set, the copy operation will attempt to use the hard link facility instead of copy the file (to save disk space). If the link operation fails, it falls back to the copy operation. The copy operation copies up to 4096 bytes at once.
Definition at line 3539 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, errno, and VOICEMAIL_FILE_MODE.
Referenced by copy_plain_file().
03540 { 03541 int ifd; 03542 int ofd; 03543 int res; 03544 int len; 03545 char buf[4096]; 03546 03547 #ifdef HARDLINK_WHEN_POSSIBLE 03548 /* Hard link if possible; saves disk space & is faster */ 03549 if (link(infile, outfile)) { 03550 #endif 03551 if ((ifd = open(infile, O_RDONLY)) < 0) { 03552 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 03553 return -1; 03554 } 03555 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 03556 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 03557 close(ifd); 03558 return -1; 03559 } 03560 do { 03561 len = read(ifd, buf, sizeof(buf)); 03562 if (len < 0) { 03563 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 03564 close(ifd); 03565 close(ofd); 03566 unlink(outfile); 03567 } 03568 if (len) { 03569 res = write(ofd, buf, len); 03570 if (errno == ENOMEM || errno == ENOSPC || res != len) { 03571 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 03572 close(ifd); 03573 close(ofd); 03574 unlink(outfile); 03575 } 03576 } 03577 } while (len); 03578 close(ifd); 03579 close(ofd); 03580 return 0; 03581 #ifdef HARDLINK_WHEN_POSSIBLE 03582 } else { 03583 /* Hard link succeeded */ 03584 return 0; 03585 } 03586 #endif 03587 }
| 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 | This is only used by file storage based mailboxes. |
Definition at line 4698 of file app_voicemail.c.
References ast_copy_string(), ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, ast_strlen_zero(), ast_unlock_path(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, COPY, copy_plain_file(), create_dirpath(), ERROR_LOCK_PATH, EXISTS, last_message_index(), ast_vm_user::mailbox, make_dir(), make_file(), mbox(), notify_new_message(), S_OR, STORE, vm_delete(), and vm_lock_path().
Referenced by forward_message(), and leave_voicemail().
04699 { 04700 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 04701 const char *frombox = mbox(imbox); 04702 int recipmsgnum; 04703 04704 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 04705 04706 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 04707 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "Urgent"); 04708 } else { 04709 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 04710 } 04711 04712 if (!dir) 04713 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 04714 else 04715 ast_copy_string(fromdir, dir, sizeof(fromdir)); 04716 04717 make_file(frompath, sizeof(frompath), fromdir, msgnum); 04718 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 04719 04720 if (vm_lock_path(todir)) 04721 return ERROR_LOCK_PATH; 04722 04723 recipmsgnum = last_message_index(recip, todir) + 1; 04724 if (recipmsgnum < recip->maxmsg) { 04725 make_file(topath, sizeof(topath), todir, recipmsgnum); 04726 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 04727 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 04728 } else { 04729 /* For ODBC storage, if the file we want to copy isn't yet in the database, then the SQL 04730 * copy will fail. Instead, we need to create a local copy, store it, and delete the local 04731 * copy. We don't have to #ifdef this because if file storage reaches this point, there's a 04732 * much worse problem happening and IMAP storage doesn't call this function 04733 */ 04734 copy_plain_file(frompath, topath); 04735 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 04736 vm_delete(topath); 04737 } 04738 } else { 04739 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 04740 } 04741 ast_unlock_path(todir); 04742 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 04743 04744 return 0; 04745 }
| static void copy_plain_file | ( | char * | frompath, | |
| char * | topath | |||
| ) | [static] |
Copies a voicemail information (envelope) file.
| frompath | ||
| topath |
Every voicemail has the data (.wav) file, and the information file. This function performs the file system copying of the information file for a voicemail, handling the internal fields and their values. This is used by the COPY macro when not using IMAP storage.
Definition at line 3598 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().
03599 { 03600 char frompath2[PATH_MAX], topath2[PATH_MAX]; 03601 struct ast_variable *tmp,*var = NULL; 03602 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 03603 ast_filecopy(frompath, topath, NULL); 03604 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 03605 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 03606 if (ast_check_realtime("voicemail_data")) { 03607 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 03608 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 03609 for (tmp = var; tmp; tmp = tmp->next) { 03610 if (!strcasecmp(tmp->name, "origmailbox")) { 03611 origmailbox = tmp->value; 03612 } else if (!strcasecmp(tmp->name, "context")) { 03613 context = tmp->value; 03614 } else if (!strcasecmp(tmp->name, "macrocontext")) { 03615 macrocontext = tmp->value; 03616 } else if (!strcasecmp(tmp->name, "exten")) { 03617 exten = tmp->value; 03618 } else if (!strcasecmp(tmp->name, "priority")) { 03619 priority = tmp->value; 03620 } else if (!strcasecmp(tmp->name, "callerchan")) { 03621 callerchan = tmp->value; 03622 } else if (!strcasecmp(tmp->name, "callerid")) { 03623 callerid = tmp->value; 03624 } else if (!strcasecmp(tmp->name, "origdate")) { 03625 origdate = tmp->value; 03626 } else if (!strcasecmp(tmp->name, "origtime")) { 03627 origtime = tmp->value; 03628 } else if (!strcasecmp(tmp->name, "category")) { 03629 category = tmp->value; 03630 } else if (!strcasecmp(tmp->name, "duration")) { 03631 duration = tmp->value; 03632 } 03633 } 03634 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); 03635 } 03636 copy(frompath2, topath2); 03637 ast_variables_destroy(var); 03638 }
| 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 3442 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().
03443 { 03444 03445 int vmcount = 0; 03446 DIR *vmdir = NULL; 03447 struct dirent *vment = NULL; 03448 03449 if (vm_lock_path(dir)) 03450 return ERROR_LOCK_PATH; 03451 03452 if ((vmdir = opendir(dir))) { 03453 while ((vment = readdir(vmdir))) { 03454 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03455 vmcount++; 03456 } 03457 } 03458 closedir(vmdir); 03459 } 03460 ast_unlock_path(dir); 03461 03462 return vmcount; 03463 }
| 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 1327 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
Referenced by add_email_attachment(), copy_message(), invent_message(), leave_voicemail(), open_mailbox(), and save_to_folder().
01328 { 01329 mode_t mode = VOICEMAIL_DIR_MODE; 01330 int res; 01331 01332 make_dir(dest, len, context, ext, folder); 01333 if ((res = ast_mkdir(dest, mode))) { 01334 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01335 return -1; 01336 } 01337 return 0; 01338 }
| static int dialout | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| char * | num, | |||
| char * | outgoing_context | |||
| ) | [static] |
Definition at line 11099 of file app_voicemail.c.
References ast_copy_string(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_verb, ast_verbose, ast_waitfordigit(), ast_channel::context, ast_channel::exten, option_verbose, ast_channel::priority, and VERBOSE_PREFIX_3.
Referenced by advanced_options(), and vm_execmain().
11100 { 11101 int cmd = 0; 11102 char destination[80] = ""; 11103 int retries = 0; 11104 11105 if (!num) { 11106 ast_verb(3, "Destination number will be entered manually\n"); 11107 while (retries < 3 && cmd != 't') { 11108 destination[1] = '\0'; 11109 destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call"); 11110 if (!cmd) 11111 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 11112 if (!cmd) 11113 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 11114 if (!cmd) { 11115 cmd = ast_waitfordigit(chan, 6000); 11116 if (cmd) 11117 destination[0] = cmd; 11118 } 11119 if (!cmd) { 11120 retries++; 11121 } else { 11122 11123 if (cmd < 0) 11124 return 0; 11125 if (cmd == '*') { 11126 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 11127 return 0; 11128 } 11129 if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 11130 retries++; 11131 else 11132 cmd = 't'; 11133 } 11134 } 11135 if (retries >= 3) { 11136 return 0; 11137 } 11138 11139 } else { 11140 if (option_verbose > 2) 11141 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 11142 ast_copy_string(destination, num, sizeof(destination)); 11143 } 11144 11145 if (!ast_strlen_zero(destination)) { 11146 if (destination[strlen(destination) -1 ] == '*') 11147 return 0; 11148 if (option_verbose > 2) 11149 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 11150 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 11151 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 11152 chan->priority = 0; 11153 return 9; 11154 } 11155 return 0; 11156 }
| static char* encode_mime_str | ( | const char * | start, | |
| char * | end, | |||
| size_t | endsize, | |||
| 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.
| start | A string to be encoded | |
| end | An expandable buffer for holding the result | |
| 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 3924 of file app_voicemail.c.
References charset.
Referenced by make_email_file().
03925 { 03926 char tmp[80]; 03927 int first_section = 1; 03928 size_t endlen = 0, tmplen = 0; 03929 *end = '\0'; 03930 03931 tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset); 03932 for (; *start; start++) { 03933 int need_encoding = 0; 03934 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 03935 need_encoding = 1; 03936 } 03937 if ((first_section && need_encoding && preamble + tmplen > 70) || 03938 (first_section && !need_encoding && preamble + tmplen > 72) || 03939 (!first_section && need_encoding && tmplen > 70) || 03940 (!first_section && !need_encoding && tmplen > 72)) { 03941 /* Start new line */ 03942 endlen += snprintf(end + endlen, endsize - endlen, "%s%s?=", first_section ? "" : " ", tmp); 03943 tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset); 03944 first_section = 0; 03945 } 03946 if (need_encoding && *start == ' ') { 03947 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "_"); 03948 } else if (need_encoding) { 03949 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "=%hhX", *start); 03950 } else { 03951 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%c", *start); 03952 } 03953 } 03954 snprintf(end + endlen, endsize - endlen, "%s%s?=%s", first_section ? "" : " ", tmp, endlen + postamble > 74 ? " " : ""); 03955 return end; 03956 }
| static struct ast_vm_user* find_or_create | ( | const char * | context, | |
| const char * | box | |||
| ) | [static, read] |
Definition at line 9638 of file app_voicemail.c.
References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_test_flag, ast_vm_user::context, globalflags, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
Referenced by append_mailbox(), and load_config().
09639 { 09640 struct ast_vm_user *vmu; 09641 09642 AST_LIST_TRAVERSE(&users, vmu, list) { 09643 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 09644 if (strcasecmp(vmu->context, context)) { 09645 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 09646 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 09647 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 09648 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 09649 } 09650 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 09651 return NULL; 09652 } 09653 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 09654 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 09655 return NULL; 09656 } 09657 } 09658 09659 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 09660 return NULL; 09661 09662 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 09663 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 09664 09665 AST_LIST_INSERT_TAIL(&users, vmu, list); 09666 09667 return vmu; 09668 }
| 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 1123 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_malloc, ast_set2_flag, ast_test_flag, find_user_realtime(), globalflags, VM_ALLOCED, and VM_SEARCH.
Referenced by acf_mailbox_exists(), advanced_options(), forward_message(), leave_voicemail(), vm_authenticate(), vm_box_exists(), and vm_execmain().
01124 { 01125 /* This function could be made to generate one from a database, too */ 01126 struct ast_vm_user *vmu=NULL, *cur; 01127 AST_LIST_LOCK(&users); 01128 01129 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01130 context = "default"; 01131 01132 AST_LIST_TRAVERSE(&users, cur, list) { 01133 #ifdef IMAP_STORAGE 01134 if (cur->imapversion != imapversion) { 01135 continue; 01136 } 01137 #endif 01138 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01139 break; 01140 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01141 break; 01142 } 01143 if (cur) { 01144 /* Make a copy, so that on a reload, we have no race */ 01145 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01146 memcpy(vmu, cur, sizeof(*vmu)); 01147 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01148 AST_LIST_NEXT(vmu, list) = NULL; 01149 } 01150 } else 01151 vmu = find_user_realtime(ivm, context, mailbox); 01152 AST_LIST_UNLOCK(&users); 01153 return vmu; 01154 }
| 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 1086 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.
Referenced by find_user().
01087 { 01088 struct ast_variable *var; 01089 struct ast_vm_user *retval; 01090 01091 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01092 if (!ivm) 01093 ast_set_flag(retval, VM_ALLOCED); 01094 else 01095 memset(retval, 0, sizeof(*retval)); 01096 if (mailbox) 01097 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01098 populate_defaults(retval); 01099 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) 01100 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01101 else 01102 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01103 if (var) { 01104 apply_options_full(retval, var); 01105 ast_variables_destroy(var); 01106 } else { 01107 if (!ivm) 01108 ast_free(retval); 01109 retval = NULL; 01110 } 01111 } 01112 return retval; 01113 }
| 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.
| ast_channel | ||
| 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 |
Reads the destination mailbox(es) from keypad input for CID, or if use_directory feature is enabled, the Directory.
When in the leave message mode (is_new_message == 1):
When in the forward message mode (is_new_message == 0):
Definition at line 6366 of file app_voicemail.c.
References ast_clear_flag, ast_copy_string(), ast_fileexists(), 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_waitfordigit(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, 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, leave_voicemail(), LOG_NOTICE, ast_vm_user::mailbox, pbx_exec(), pbx_findapp(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, run_externnotify(), s, S_OR, sendmail(), STORE, strsep(), vm_state::username, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), and VM_FWDURGAUTO.
Referenced by vm_execmain().
06367 { 06368 #ifdef IMAP_STORAGE 06369 int todircount=0; 06370 struct vm_state *dstvms; 06371 #endif 06372 char username[70]=""; 06373 char fn[PATH_MAX]; /* for playback of name greeting */ 06374 char ecodes[16] = "#"; 06375 int res = 0, cmd = 0; 06376 struct ast_vm_user *receiver = NULL, *vmtmp; 06377 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 06378 char *stringp; 06379 const char *s; 06380 int saved_messages = 0, found = 0; 06381 int valid_extensions = 0; 06382 char *dir; 06383 int curmsg; 06384 char urgent_str[7] = ""; 06385 char tmptxtfile[PATH_MAX]; 06386 06387 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 06388 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 06389 } 06390 06391 if (vms == NULL) return -1; 06392 dir = vms->curdir; 06393 curmsg = vms->curmsg; 06394 06395 tmptxtfile[0] = '\0'; 06396 while (!res && !valid_extensions) { 06397 int use_directory = 0; 06398 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 06399 int done = 0; 06400 int retries = 0; 06401 cmd=0; 06402 while ((cmd >= 0) && !done ){ 06403 if (cmd) 06404 retries = 0; 06405 switch (cmd) { 06406 case '1': 06407 use_directory = 0; 06408 done = 1; 06409 break; 06410 case '2': 06411 use_directory = 1; 06412 done=1; 06413 break; 06414 case '*': 06415 cmd = 't'; 06416 done = 1; 06417 break; 06418 default: 06419 /* Press 1 to enter an extension press 2 to use the directory */ 06420 cmd = ast_play_and_wait(chan,"vm-forward"); 06421 if (!cmd) 06422 cmd = ast_waitfordigit(chan,3000); 06423 if (!cmd) 06424 retries++; 06425 if (retries > 3) { 06426 cmd = 't'; 06427 done = 1; 06428 } 06429 06430 } 06431 } 06432 if (cmd < 0 || cmd == 't') 06433 break; 06434 } 06435 06436 if (use_directory) { 06437 /* use app_directory */ 06438 06439 char old_context[sizeof(chan->context)]; 06440 char old_exten[sizeof(chan->exten)]; 06441 int old_priority; 06442 struct ast_app* directory_app; 06443 06444 directory_app = pbx_findapp("Directory"); 06445 if (directory_app) { 06446 char vmcontext[256]; 06447 /* make backup copies */ 06448 memcpy(old_context, chan->context, sizeof(chan->context)); 06449 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 06450 old_priority = chan->priority; 06451 06452 /* call the the Directory, changes the channel */ 06453 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 06454 res = pbx_exec(chan, directory_app, vmcontext); 06455 06456 ast_copy_string(username, chan->exten, sizeof(username)); 06457 06458 /* restore the old context, exten, and priority */ 06459 memcpy(chan->context, old_context, sizeof(chan->context)); 06460 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 06461 chan->priority = old_priority; 06462 } else { 06463 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 06464 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 06465 } 06466 } else { 06467 /* Ask for an extension */ 06468 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 06469 if (res) 06470 break; 06471 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 06472 break; 06473 } 06474 06475 /* start all over if no username */ 06476 if (ast_strlen_zero(username)) 06477 continue; 06478 stringp = username; 06479 s = strsep(&stringp, "*"); 06480 /* start optimistic */ 06481 valid_extensions = 1; 06482 while (s) { 06483 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 06484 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 06485 found++; 06486 } else { 06487 /* XXX Optimization for the future. When we encounter a single bad extension, 06488 * bailing out on all of the extensions may not be the way to go. We should 06489 * probably just bail on that single extension, then allow the user to enter 06490 * several more. XXX 06491 */ 06492 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 06493 free_user(receiver); 06494 } 06495 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 06496 valid_extensions = 0; 06497 break; 06498 } 06499 06500 /* play name if available, else play extension number */ 06501 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 06502 RETRIEVE(fn, -1, s, receiver->context); 06503 if (ast_fileexists(fn, NULL, NULL) > 0) { 06504 res = ast_stream_and_wait(chan, fn, ecodes); 06505 if (res) { 06506 DISPOSE(fn, -1); 06507 return res; 06508 } 06509 } else { 06510 res = ast_say_digit_str(chan, s, ecodes, chan->language); 06511 } 06512 DISPOSE(fn, -1); 06513 06514 s = strsep(&stringp, "*"); 06515 } 06516 /* break from the loop of reading the extensions */ 06517 if (valid_extensions) 06518 break; 06519 /* "I am sorry, that's not a valid extension. Please try again." */ 06520 res = ast_play_and_wait(chan, "pbx-invalid"); 06521 } 06522 /* check if we're clear to proceed */ 06523 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 06524 return res; 06525 if (is_new_message == 1) { 06526 struct leave_vm_options leave_options; 06527 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 06528 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 06529 06530 /* Send VoiceMail */ 06531 memset(&leave_options, 0, sizeof(leave_options)); 06532 leave_options.record_gain = record_gain; 06533 cmd = leave_voicemail(chan, mailbox, &leave_options); 06534 } else { 06535 /* Forward VoiceMail */ 06536 long duration = 0; 06537 struct vm_state vmstmp; 06538 memcpy(&vmstmp, vms, sizeof(vmstmp)); 06539 06540 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 06541 06542 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 06543 if (!cmd) { 06544 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 06545 #ifdef IMAP_STORAGE 06546 int attach_user_voicemail; 06547 char *myserveremail = serveremail; 06548 06549 /* get destination mailbox */ 06550 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 06551 if (!dstvms) { 06552 dstvms = create_vm_state_from_user(vmtmp); 06553 } 06554 if (dstvms) { 06555 init_mailstream(dstvms, 0); 06556 if (!dstvms->mailstream) { 06557 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 06558 } else { 06559 STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 06560 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 06561 } 06562 } else { 06563 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 06564 } 06565 if (!ast_strlen_zero(vmtmp->serveremail)) 06566 myserveremail = vmtmp->serveremail; 06567 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 06568 /* NULL category for IMAP storage */ 06569 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, dstvms->curbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, NULL, urgent_str); 06570 #else 06571 copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 06572 #endif 06573 saved_messages++; 06574 AST_LIST_REMOVE_CURRENT(list); 06575 free_user(vmtmp); 06576 if (res) 06577 break; 06578 } 06579 AST_LIST_TRAVERSE_SAFE_END; 06580 if (saved_messages > 0) { 06581 /* give confirmation that the message was saved */ 06582 /* commented out since we can't forward batches yet 06583 if (saved_messages == 1) 06584 res = ast_play_and_wait(chan, "vm-message"); 06585 else 06586 res = ast_play_and_wait(chan, "vm-messages"); 06587 if (!res) 06588 res = ast_play_and_wait(chan, "vm-saved"); */ 06589 #ifdef IMAP_STORAGE 06590 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 06591 if (ast_strlen_zero(vmstmp.introfn)) 06592 #endif 06593 res = ast_play_and_wait(chan, "vm-msgsaved"); 06594 } 06595 } 06596 DISPOSE(dir, curmsg); 06597 } 06598 06599 /* If anything failed above, we still have this list to free */ 06600 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) 06601 free_user(vmtmp); 06602 return res ? res : cmd; 06603 }
| static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1363 of file app_voicemail.c.
References ast_free, ast_test_flag, and VM_ALLOCED.
Referenced by forward_message(), free_vm_users(), leave_voicemail(), and vm_execmain().
01364 { 01365 if (ast_test_flag(vmu, VM_ALLOCED)) 01366 ast_free(vmu); 01367 }
| static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 10311 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 load_config(), and unload_module().
10312 { 10313 struct ast_vm_user *current; 10314 AST_LIST_LOCK(&users); 10315 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 10316 ast_set_flag(current, VM_ALLOCED); 10317 free_user(current); 10318 } 10319 AST_LIST_UNLOCK(&users); 10320 }
| static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 10323 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free_zone().
Referenced by load_config(), and unload_module().
10324 { 10325 struct vm_zone *zcur; 10326 AST_LIST_LOCK(&zones); 10327 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 10328 free_zone(zcur); 10329 AST_LIST_UNLOCK(&zones); 10330 }
| static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 4465 of file app_voicemail.c.
References ast_free.
Referenced by free_vm_zones().
04466 { 04467 ast_free(z); 04468 }
| static int get_date | ( | char * | s, | |
| int | len | |||
| ) | [static] |
Gets the current date and time, as formatted string.
| s | The buffer to hold the output formatted date. | |
| len | the length of the buffer. Used to prevent buffer overflow in ast_strftime. |
The date format string used is "%a %b %e %r UTC %Y".
Definition at line 4421 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail().
04422 { 04423 struct ast_tm tm; 04424 struct timeval t = ast_tvnow(); 04425 04426 ast_localtime(&t, &tm, "UTC"); 04427 04428 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 04429 }
| 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 6032 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_waitfordigit(), mbox(), and vm_play_folder_name().
Referenced by get_folder2().
06033 { 06034 int x; 06035 int d; 06036 char fn[PATH_MAX]; 06037 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06038 if (d) 06039 return d; 06040 for (x = start; x< 5; x++) { /* For all folders */ 06041 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06042 return d; 06043 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06044 if (d) 06045 return d; 06046 snprintf(fn, sizeof(fn), "vm-%s", mbox(x)); /* Folder name */ 06047 d = vm_play_folder_name(chan, fn); 06048 if (d) 06049 return d; 06050 d = ast_waitfordigit(chan, 500); 06051 if (d) 06052 return d; 06053 } 06054 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06055 if (d) 06056 return d; 06057 d = ast_waitfordigit(chan, 4000); 06058 return d; 06059 }
| static int get_folder2 | ( | struct ast_channel * | chan, | |
| char * | fn, | |||
| int | start | |||
| ) | [static] |
plays a prompt and waits for a keypress.
| chan | ||
| fn | the name of the voice prompt file to be played. For example, 'vm-changeto', 'vm-savefolder' | |
| start | Does not appear to be used at this time. |
This is used by the main menu option to move a message to a folder or to save a message into a folder. After playing the message identified by the fn parameter value, it calls get_folder(), which plays the prompting for the number inputs that correspond to the available folders.
Definition at line 6073 of file app_voicemail.c.
References ast_play_and_wait(), and get_folder().
Referenced by vm_execmain().
06074 { 06075 int res = 0; 06076 res = ast_play_and_wait(chan, fn); /* Folder name */ 06077 while (((res < '0') || (res > '9')) && 06078 (res != '#') && (res >= 0)) { 06079 res = get_folder(chan, 0); 06080 } 06081 return res; 06082 }
| static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 10094 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().
10095 { 10096 unsigned int len; 10097 struct mwi_sub *mwi_sub; 10098 struct mwi_sub_task *p = datap; 10099 10100 len = sizeof(*mwi_sub); 10101 if (!ast_strlen_zero(p->mailbox)) 10102 len += strlen(p->mailbox); 10103 10104 if (!ast_strlen_zero(p->context)) 10105 len += strlen(p->context) + 1; /* Allow for seperator */ 10106 10107 if (!(mwi_sub = ast_calloc(1, len))) 10108 return -1; 10109 10110 mwi_sub->uniqueid = p->uniqueid; 10111 if (!ast_strlen_zero(p->mailbox)) 10112 strcpy(mwi_sub->mailbox, p->mailbox); 10113 10114 if (!ast_strlen_zero(p->context)) { 10115 strcat(mwi_sub->mailbox, "@"); 10116 strcat(mwi_sub->mailbox, p->context); 10117 } 10118 10119 AST_RWLIST_WRLOCK(&mwi_subs); 10120 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 10121 AST_RWLIST_UNLOCK(&mwi_subs); 10122 ast_free((void *) p->mailbox); 10123 ast_free((void *) p->context); 10124 ast_free(p); 10125 poll_subscribed_mailbox(mwi_sub); 10126 return 0; 10127 }
| static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 10072 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().
10073 { 10074 struct mwi_sub *mwi_sub; 10075 uint32_t *uniqueid = datap; 10076 10077 AST_RWLIST_WRLOCK(&mwi_subs); 10078 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 10079 if (mwi_sub->uniqueid == *uniqueid) { 10080 AST_LIST_REMOVE_CURRENT(entry); 10081 break; 10082 } 10083 } 10084 AST_RWLIST_TRAVERSE_SAFE_END 10085 AST_RWLIST_UNLOCK(&mwi_subs); 10086 10087 if (mwi_sub) 10088 mwi_sub_destroy(mwi_sub); 10089 10090 ast_free(uniqueid); 10091 return 0; 10092 }
| 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 9989 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.
09990 { 09991 switch (cmd) { 09992 case CLI_INIT: 09993 e->command = "voicemail reload"; 09994 e->usage = 09995 "Usage: voicemail reload\n" 09996 " Reload voicemail configuration\n"; 09997 return NULL; 09998 case CLI_GENERATE: 09999 return NULL; 10000 } 10001 10002 if (a->argc != 2) 10003 return CLI_SHOWUSAGE; 10004 10005 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 10006 load_config(1); 10007 10008 return CLI_SUCCESS; 10009 }
| 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 9879 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.
09880 { 09881 struct ast_vm_user *vmu; 09882 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 09883 const char *context = NULL; 09884 int users_counter = 0; 09885 09886 switch (cmd) { 09887 case CLI_INIT: 09888 e->command = "voicemail show users"; 09889 e->usage = 09890 "Usage: voicemail show users [for <context>]\n" 09891 " Lists all mailboxes currently set up\n"; 09892 return NULL; 09893 case CLI_GENERATE: 09894 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 09895 } 09896 09897 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 09898 return CLI_SHOWUSAGE; 09899 if (a->argc == 5) { 09900 if (strcmp(a->argv[3],"for")) 09901 return CLI_SHOWUSAGE; 09902 context = a->argv[4]; 09903 } 09904 09905 if (ast_check_realtime("voicemail")) { 09906 if (!context) { 09907 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 09908 return CLI_SHOWUSAGE; 09909 } 09910 return show_users_realtime(a->fd, context); 09911 } 09912 09913 AST_LIST_LOCK(&users); 09914 if (AST_LIST_EMPTY(&users)) { 09915 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 09916 AST_LIST_UNLOCK(&users); 09917 return CLI_FAILURE; 09918 } 09919 if (a->argc == 3) 09920 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 09921 else { 09922 int count = 0; 09923 AST_LIST_TRAVERSE(&users, vmu, list) { 09924 if (!strcmp(context, vmu->context)) 09925 count++; 09926 } 09927 if (count) { 09928 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 09929 } else { 09930 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 09931 AST_LIST_UNLOCK(&users); 09932 return CLI_FAILURE; 09933 } 09934 } 09935 AST_LIST_TRAVERSE(&users, vmu, list) { 09936 int newmsgs = 0, oldmsgs = 0; 09937 char count[12], tmp[256] = ""; 09938 09939 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 09940 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 09941 inboxcount(tmp, &newmsgs, &oldmsgs); 09942 snprintf(count, sizeof(count), "%d", newmsgs); 09943 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 09944 users_counter++; 09945 } 09946 } 09947 AST_LIST_UNLOCK(&users); 09948 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 09949 return CLI_SUCCESS; 09950 }
| 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 9953 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.
09954 { 09955 struct vm_zone *zone; 09956 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 09957 char *res = CLI_SUCCESS; 09958 09959 switch (cmd) { 09960 case CLI_INIT: 09961 e->command = "voicemail show zones"; 09962 e->usage = 09963 "Usage: voicemail show zones\n" 09964 " Lists zone message formats\n"; 09965 return NULL; 09966 case CLI_GENERATE: 09967 return NULL; 09968 } 09969 09970 if (a->argc != 3) 09971 return CLI_SHOWUSAGE; 09972 09973 AST_LIST_LOCK(&zones); 09974 if (!AST_LIST_EMPTY(&zones)) { 09975 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 09976 AST_LIST_TRAVERSE(&zones, zone, list) { 09977 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 09978 } 09979 } else { 09980 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 09981 res = CLI_FAILURE; 09982 } 09983 AST_LIST_UNLOCK(&zones); 09984 09985 return res; 09986 }
| static int has_voicemail | ( | const char * | mailbox, | |
| const char * | folder | |||
| ) | [static] |
Determines if the given folder has messages.
| mailbox | The @ delimited string for user. If no context is found, uses 'default' for the context. | |
| folder | the folder to look in |
This function is used when the mailbox is stored in a filesystem back end. This invokes the messagecount(). Here we are interested in the presence of messages (> 0) only, not the actual count.
Definition at line 4806 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), and strsep().
Referenced by load_module(), and vm_execmain().
04807 { 04808 char tmp[256], *tmp2 = tmp, *box, *context; 04809 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04810 while ((box = strsep(&tmp2, ","))) { 04811 if ((context = strchr(box, '@'))) 04812 *context++ = '\0'; 04813 else 04814 context = "default"; 04815 if (__has_voicemail(context, box, folder, 1)) 04816 return 1; 04817 } 04818 return 0; 04819 }
| static int inboxcount | ( | const char * | mailbox, | |
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) | [static] |
Definition at line 4878 of file app_voicemail.c.
References inboxcount2().
Referenced by handle_voicemail_show_users(), leave_voicemail(), load_module(), and manager_list_voicemail_users().
04879 { 04880 return inboxcount2(mailbox, NULL, newmsgs, oldmsgs); 04881 }
| static int inboxcount2 | ( | const char * | mailbox, | |
| int * | urgentmsgs, | |||
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) | [static] |
Definition at line 4822 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(), and run_externnotify().
04823 { 04824 char tmp[256]; 04825 char *context; 04826 04827 /* If no mailbox, return immediately */ 04828 if (ast_strlen_zero(mailbox)) 04829 return 0; 04830 04831 if (newmsgs) 04832 *newmsgs = 0; 04833 if (oldmsgs) 04834 *oldmsgs = 0; 04835 if (urgentmsgs) 04836 *urgentmsgs = 0; 04837 04838 if (strchr(mailbox, ',')) { 04839 int tmpnew, tmpold, tmpurgent; 04840 char *mb, *cur; 04841 04842 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04843 mb = tmp; 04844 while ((cur = strsep(&mb, ", "))) { 04845 if (!ast_strlen_zero(cur)) { 04846 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 04847 return -1; 04848 else { 04849 if (newmsgs) 04850 *newmsgs += tmpnew; 04851 if (oldmsgs) 04852 *oldmsgs += tmpold; 04853 if (urgentmsgs) 04854 *urgentmsgs += tmpurgent; 04855 } 04856 } 04857 } 04858 return 0; 04859 } 04860 04861 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04862 04863 if ((context = strchr(tmp, '@'))) 04864 *context++ = '\0'; 04865 else 04866 context = "default"; 04867 04868 if (newmsgs) 04869 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 04870 if (oldmsgs) 04871 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 04872 if (urgentmsgs) 04873 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 04874 04875 return 0; 04876 }
| static int inbuf | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
utility used by inchar(), for base_encode()
Definition at line 3670 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(), and sip_addheader().
| static int inchar | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
utility used by base_encode()
Definition at line 3694 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
| static int invent_message | ( | struct ast_channel * | chan, | |
| char * | context, | |||
| char * | ext, | |||
| int | busy, | |||
| char * | ecodes | |||
| ) | [static] |
Definition at line 4431 of file app_voicemail.c.
References ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, and RETRIEVE.
Referenced by leave_voicemail().
04432 { 04433 int res; 04434 char fn[PATH_MAX]; 04435 char dest[PATH_MAX]; 04436 04437 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 04438 04439 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 04440 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 04441 return -1; 04442 } 04443 04444 RETRIEVE(fn, -1, ext, context); 04445 if (ast_fileexists(fn, NULL, NULL) > 0) { 04446 res = ast_stream_and_wait(chan, fn, ecodes); 04447 if (res) { 04448 DISPOSE(fn, -1); 04449 return res; 04450 } 04451 } else { 04452 /* Dispose just in case */ 04453 DISPOSE(fn, -1); 04454 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 04455 if (res) 04456 return res; 04457 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 04458 if (res) 04459 return res; 04460 } 04461 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 04462 return res; 04463 }
| static int is_valid_dtmf | ( | const char * | key | ) | [static] |
Determines if a DTMF key entered is valid.
| key | The character to be compared. expects a single character. Though is capable of handling a string, this is internally copies using ast_strdupa. |
Tests the character entered against the set of valid DTMF characters.
Definition at line 1061 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by load_config().
01062 { 01063 int i; 01064 char *local_key = ast_strdupa(key); 01065 01066 for (i = 0; i < strlen(key); ++i) { 01067 if (!strchr(VALID_DTMF, *local_key)) { 01068 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01069 return 0; 01070 } 01071 local_key++; 01072 } 01073 return 1; 01074 }
| static int last_message_index | ( | struct ast_vm_user * | vmu, | |
| char * | dir | |||
| ) | [static] |
Determines the highest message number in use for a given user and mailbox folder.
| vmu | ||
| dir | the folder the mailbox folder to look for messages. Used to construct the SQL where clause. |
This method is used when mailboxes are stored on the filesystem. (not ODBC and not IMAP). Typical use to set the msgnum would be to take the value returned from this method and add one to it.
Definition at line 3496 of file app_voicemail.c.
References map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
Referenced by copy_message(), leave_voicemail(), open_mailbox(), and save_to_folder().
03497 { 03498 int x; 03499 unsigned char map[MAXMSGLIMIT] = ""; 03500 DIR *msgdir; 03501 struct dirent *msgdirent; 03502 int msgdirint; 03503 03504 /* Reading the entire directory into a file map scales better than 03505 * doing a stat repeatedly on a predicted sequence. I suspect this 03506 * is partially due to stat(2) internally doing a readdir(2) itself to 03507 * find each file. */ 03508 if (!(msgdir = opendir(dir))) { 03509 return -1; 03510 } 03511 03512 while ((msgdirent = readdir(msgdir))) { 03513 if (sscanf(msgdirent->d_name, "msg%30d", &msgdirint) == 1 && msgdirint < MAXMSGLIMIT) 03514 map[msgdirint] = 1; 03515 } 03516 closedir(msgdir); 03517 03518 for (x = 0; x < vmu->maxmsg; x++) { 03519 if (map[x] == 0) 03520 break; 03521 } 03522 03523 return x - 1; 03524 }
| 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 4948 of file app_voicemail.c.
References ast_callerid_merge(), ast_canmatch_extension(), ast_channel_lock, ast_channel_unlock, ast_check_realtime(), ast_copy_string(), ast_debug, ast_destroy_realtime(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_free, ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, AST_LOG_WARNING, ast_mutex_lock(), ast_mutex_unlock(), ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_store_realtime(), ast_str_buffer, ast_str_create(), ast_str_set(), ast_strdupa, ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_update_realtime(), ast_verbose, ast_waitstream(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, 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(), get_date(), inboxcount(), INTRO, invent_message(), last_message_index(), ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, vm_state::newmessages, notify_new_message(), OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_SILENT, OPT_UNAVAIL_GREETING, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, leave_vm_options::record_gain, RENAME, RETRIEVE, S_OR, SENTINEL, STORE, strsep(), transfer, VERBOSE_PREFIX_3, vm_lock_path(), VM_OPERATOR, and VOICEMAIL_FILE_MODE.
Referenced by advanced_options(), forward_message(), and vm_exec().
04949 { 04950 #ifdef IMAP_STORAGE 04951 int newmsgs, oldmsgs; 04952 #else 04953 char urgdir[PATH_MAX]; 04954 #endif 04955 char txtfile[PATH_MAX]; 04956 char tmptxtfile[PATH_MAX]; 04957 struct vm_state *vms = NULL; 04958 char callerid[256]; 04959 FILE *txt; 04960 char date[256]; 04961 int txtdes; 04962 int res = 0; 04963 int msgnum; 04964 int duration = 0; 04965 int ausemacro = 0; 04966 int ousemacro = 0; 04967 int ouseexten = 0; 04968 int rtmsgid = 0; 04969 char tmpid[16]; 04970 char tmpdur[16]; 04971 char priority[16]; 04972 char origtime[16]; 04973 char dir[PATH_MAX]; 04974 char tmpdir[PATH_MAX]; 04975 char fn[PATH_MAX]; 04976 char prefile[PATH_MAX] = ""; 04977 char tempfile[PATH_MAX] = ""; 04978 char ext_context[256] = ""; 04979 char fmt[80]; 04980 char *context; 04981 char ecodes[17] = "#"; 04982 struct ast_str *tmp = ast_str_create(16); 04983 char *tmpptr; 04984 struct ast_vm_user *vmu; 04985 struct ast_vm_user svm; 04986 const char *category = NULL; 04987 const char *code; 04988 const char *alldtmf = "0123456789ABCD*#"; 04989 char flag[80]; 04990 04991 ast_str_set(&tmp, 0, "%s", ext); 04992 ext = ast_str_buffer(tmp); 04993 if ((context = strchr(ext, '@'))) { 04994 *context++ = '\0'; 04995 tmpptr = strchr(context, '&'); 04996 } else { 04997 tmpptr = strchr(ext, '&'); 04998 } 04999 05000 if (tmpptr) 05001 *tmpptr++ = '\0'; 05002 05003 ast_channel_lock(chan); 05004 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05005 category = ast_strdupa(category); 05006 } 05007 ast_channel_unlock(chan); 05008 05009 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05010 ast_copy_string(flag, "Urgent", sizeof(flag)); 05011 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05012 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05013 } else { 05014 flag[0] = '\0'; 05015 } 05016 05017 ast_debug(3, "Before find_user\n"); 05018 if (!(vmu = find_user(&svm, context, ext))) { 05019 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05020 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05021 ast_free(tmp); 05022 return res; 05023 } 05024 /* Setup pre-file if appropriate */ 05025 if (strcmp(vmu->context, "default")) 05026 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05027 else 05028 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05029 05030 /* Set the path to the prefile. Will be one of 05031 VM_SPOOL_DIRcontext/ext/busy 05032 VM_SPOOL_DIRcontext/ext/unavail 05033 Depending on the flag set in options. 05034 */ 05035 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05036 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05037 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05038 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05039 } 05040 /* Set the path to the tmpfile as 05041 VM_SPOOL_DIR/context/ext/temp 05042 and attempt to create the folder structure. 05043 */ 05044 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05045 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05046 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05047 ast_free(tmp); 05048 return -1; 05049 } 05050 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05051 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05052 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05053 05054 DISPOSE(tempfile, -1); 05055 /* It's easier just to try to make it than to check for its existence */ 05056 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05057 05058 /* Check current or macro-calling context for special extensions */ 05059 if (ast_test_flag(vmu, VM_OPERATOR)) { 05060 if (!ast_strlen_zero(vmu->exit)) { 05061 if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) { 05062 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05063 ouseexten = 1; 05064 } 05065 } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) { 05066 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05067 ouseexten = 1; 05068 } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) { 05069 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05070 ousemacro = 1; 05071 } 05072 } 05073 05074 if (!ast_strlen_zero(vmu->exit)) { 05075 if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num)) 05076 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05077 } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) 05078 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05079 else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) { 05080 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05081 ausemacro = 1; 05082 } 05083 05084 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05085 for (code = alldtmf; *code; code++) { 05086 char e[2] = ""; 05087 e[0] = *code; 05088 if (strchr(ecodes, e[0]) == NULL && ast_canmatch_extension(chan, chan->context, e, 1, chan->cid.cid_num)) 05089 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05090 } 05091 } 05092 05093 /* Play the beginning intro if desired */ 05094 if (!ast_strlen_zero(prefile)) { 05095 #ifdef ODBC_STORAGE 05096 int success = 05097 #endif 05098 RETRIEVE(prefile, -1, ext, context); 05099 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05100 if (ast_streamfile(chan, prefile, chan->language) > -1) 05101 res = ast_waitstream(chan, ecodes); 05102 #ifdef ODBC_STORAGE 05103 if (success == -1) { 05104 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05105 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05106 store_file(prefile, vmu->mailbox, vmu->context, -1); 05107 } 05108 #endif 05109 } else { 05110 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05111 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05112 } 05113 DISPOSE(prefile, -1); 05114 if (res < 0) { 05115 ast_debug(1, "Hang up during prefile playback\n"); 05116 free_user(vmu); 05117 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05118 ast_free(tmp); 05119 return -1; 05120 } 05121 } 05122 if (res == '#') { 05123 /* On a '#' we skip the instructions */ 05124 ast_set_flag(options, OPT_SILENT); 05125 res = 0; 05126 } 05127 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05128 res = ast_stream_and_wait(chan, INTRO, ecodes); 05129 if (res == '#') { 05130 ast_set_flag(options, OPT_SILENT); 05131 res = 0; 05132 } 05133 } 05134 if (res > 0) 05135 ast_stopstream(chan); 05136 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05137 other than the operator -- an automated attendant or mailbox login for example */ 05138 if (res == '*') { 05139 chan->exten[0] = 'a'; 05140 chan->exten[1] = '\0'; 05141 if (!ast_strlen_zero(vmu->exit)) { 05142 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05143 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05144 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05145 } 05146 chan->priority = 0; 05147 free_user(vmu); 05148 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05149 ast_free(tmp); 05150 return 0; 05151 } 05152 05153 /* Check for a '0' here */ 05154 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05155 transfer: 05156 if (ouseexten || ousemacro) { 05157 chan->exten[0] = 'o'; 05158 chan->exten[1] = '\0'; 05159 if (!ast_strlen_zero(vmu->exit)) { 05160 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05161 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05162 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05163 } 05164 ast_play_and_wait(chan, "transfer"); 05165 chan->priority = 0; 05166 free_user(vmu); 05167 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05168 } 05169 ast_free(tmp); 05170 return 0; 05171 } 05172 05173 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05174 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05175 if (!ast_strlen_zero(options->exitcontext)) 05176 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05177 free_user(vmu); 05178 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05179 ast_free(tmp); 05180 return res; 05181 } 05182 05183 if (res < 0) { 05184 free_user(vmu); 05185 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05186 ast_free(tmp); 05187 return -1; 05188 } 05189 /* The meat of recording the message... All the announcements and beeps have been played*/ 05190 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05191 if (!ast_strlen_zero(fmt)) { 05192 msgnum = 0; 05193 05194 #ifdef IMAP_STORAGE 05195 /* Is ext a mailbox? */ 05196 /* must open stream for this user to get info! */ 05197 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05198 if (res < 0) { 05199 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05200 ast_free(tmp); 05201 return -1; 05202 } 05203 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05204 /* It is possible under certain circumstances that inboxcount did not 05205 * create a vm_state when it was needed. This is a catchall which will 05206 * rarely be used. 05207 */ 05208 if (!(vms = create_vm_state_from_user(vmu))) { 05209 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05210 ast_free(tmp); 05211 return -1; 05212 } 05213 } 05214 vms->newmessages++; 05215 05216 /* here is a big difference! We add one to it later */ 05217 msgnum = newmsgs + oldmsgs; 05218 ast_debug(3, "Messagecount set to %d\n",msgnum); 05219 snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05220 /* set variable for compatibility */ 05221 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05222 05223 /* Check if mailbox is full */ 05224 check_quota(vms, imapfolder); 05225 if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) { 05226 ast_debug(1, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit); 05227 ast_play_and_wait(chan, "vm-mailboxfull"); 05228 ast_free(tmp); 05229 return -1; 05230 } 05231 05232 /* Check if we have exceeded maxmsg */ 05233 if (msgnum >= vmu->maxmsg) { 05234 ast_log(AST_LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg); 05235 ast_play_and_wait(chan, "vm-mailboxfull"); 05236 ast_free(tmp); 05237 return -1; 05238 } 05239 #else 05240 if (count_messages(vmu, dir) >= vmu->maxmsg) { 05241 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05242 if (!res) 05243 res = ast_waitstream(chan, ""); 05244 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05245 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05246 goto leave_vm_out; 05247 } 05248 05249 #endif 05250 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05251 txtdes = mkstemp(tmptxtfile); 05252 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05253 if (txtdes < 0) { 05254 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05255 if (!res) 05256 res = ast_waitstream(chan, ""); 05257 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05258 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05259 goto leave_vm_out; 05260 } 05261 05262 /* Now play the beep once we have the message number for our next message. */ 05263 if (res >= 0) { 05264 /* Unless we're *really* silent, try to send the beep */ 05265 res = ast_stream_and_wait(chan, "beep", ""); 05266 } 05267 05268 /* Store information in real-time storage */ 05269 if (ast_check_realtime("voicemail_data")) { 05270 snprintf(priority, sizeof(priority), "%d", chan->priority); 05271 snprintf(origtime, sizeof(origtime), "%ld", (long)time(NULL)); 05272 get_date(date, sizeof(date)); 05273 rtmsgid = ast_store_realtime("voicemail_data", "origmailbox", ext, "context", chan->context, "macrocontext", chan->macrocontext, "exten", chan->exten, "priority", priority, "callerchan", chan->name, "callerid", ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), "origdate", date, "origtime", origtime, "category", S_OR(category,""), SENTINEL); 05274 } 05275 05276 /* Store information */ 05277 txt = fdopen(txtdes, "w+"); 05278 if (txt) { 05279 get_date(date, sizeof(date)); 05280 fprintf(txt, 05281 ";\n" 05282 "; Message Information file\n" 05283 ";\n" 05284 "[message]\n" 05285 "origmailbox=%s\n" 05286 "context=%s\n" 05287 "macrocontext=%s\n" 05288 "exten=%s\n" 05289 "priority=%d\n" 05290 "callerchan=%s\n" 05291 "callerid=%s\n" 05292 "origdate=%s\n" 05293 "origtime=%ld\n" 05294 "category=%s\n", 05295 ext, 05296 chan->context, 05297 chan->macrocontext, 05298 chan->exten, 05299 chan->priority, 05300 chan->name, 05301 ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"), 05302 date, (long)time(NULL), 05303 category ? category : ""); 05304 } else 05305 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05306 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms, flag); 05307 05308 if (txt) { 05309 fprintf(txt, "flag=%s\n", flag); 05310 if (duration < vmminsecs) { 05311 fclose(txt); 05312 if (option_verbose > 2) 05313 ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminsecs); 05314 ast_filedelete(tmptxtfile, NULL); 05315 unlink(tmptxtfile); 05316 if (ast_check_realtime("voicemail_data")) { 05317 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 05318 ast_destroy_realtime("voicemail_data", "id", tmpid, SENTINEL); 05319 } 05320 } else { 05321 fprintf(txt, "duration=%d\n", duration); 05322 fclose(txt); 05323 if (vm_lock_path(dir)) { 05324 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 05325 /* Delete files */ 05326 ast_filedelete(tmptxtfile, NULL); 05327 unlink(tmptxtfile); 05328 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 05329 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 05330 unlink(tmptxtfile); 05331 ast_unlock_path(dir); 05332 if (ast_check_realtime("voicemail_data")) { 05333 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 05334 ast_destroy_realtime("voicemail_data", "id", tmpid, SENTINEL); 05335 } 05336 } else { 05337 #ifndef IMAP_STORAGE 05338 msgnum = last_message_index(vmu, dir) + 1; 05339 #endif 05340 make_file(fn, sizeof(fn), dir, msgnum); 05341 05342 /* assign a variable with the name of the voicemail file */ 05343 #ifndef IMAP_STORAGE 05344 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 05345 #else 05346 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05347 #endif 05348 05349 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 05350 ast_filerename(tmptxtfile, fn, NULL); 05351 rename(tmptxtfile, txtfile); 05352 05353 /* Properly set permissions on voicemail text descriptor file. 05354 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 05355 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 05356 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 05357 05358 ast_unlock_path(dir); 05359 if (ast_check_realtime("voicemail_data")) { 05360 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 05361 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 05362 ast_update_realtime("voicemail_data", "id", tmpid, "filename", fn, "duration", tmpdur, SENTINEL); 05363 } 05364 /* We must store the file first, before copying the message, because 05365 * ODBC storage does the entire copy with SQL. 05366 */ 05367 if (ast_fileexists(fn, NULL, NULL) > 0) { 05368 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 05369 } 05370 05371 /* Are there to be more recipients of this message? */ 05372 while (tmpptr) { 05373 struct ast_vm_user recipu, *recip; 05374 char *exten, *cntx; 05375 05376 exten = strsep(&tmpptr, "&"); 05377 cntx = strchr(exten, '@'); 05378 if (cntx) { 05379 *cntx = '\0'; 05380 cntx++; 05381 } 05382 if ((recip = find_user(&recipu, cntx, exten))) { 05383 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 05384 free_user(recip); 05385 } 05386 } 05387 #ifndef IMAP_STORAGE 05388 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 05389 /* Move the message from INBOX to Urgent folder if this is urgent! */ 05390 char sfn[PATH_MAX]; 05391 char dfn[PATH_MAX]; 05392 int x; 05393 /* It's easier just to try to make it than to check for its existence */ 05394 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 05395 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n",sfn,dfn); 05396 x = last_message_index(vmu, urgdir) + 1; 05397 make_file(sfn, sizeof(sfn), dir, msgnum); 05398 make_file(dfn, sizeof(dfn), urgdir, x); 05399 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 05400 } 05401 #endif 05402 /* Notification needs to happen after the copy, though. */ 05403 if (ast_fileexists(fn, NULL, NULL)) { 05404 #ifdef IMAP_STORAGE 05405 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 05406 #else 05407 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 05408 #endif 05409 } 05410 05411 /* Disposal needs to happen after the optional move and copy */ 05412 if (ast_fileexists(fn, NULL, NULL)) { 05413 DISPOSE(dir, msgnum); 05414 } 05415 } 05416 } 05417 } 05418 if (res == '0') { 05419 goto transfer; 05420 } else if (res > 0) 05421 res = 0; 05422 05423 if (duration < vmminsecs) 05424 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 05425 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05426 else 05427 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05428 } else 05429 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 05430 leave_vm_out: 05431 free_user(vmu); 05432 05433 #ifdef IMAP_STORAGE 05434 /* expunge message - use UID Expunge if supported on IMAP server*/ 05435 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n",expungeonhangup); 05436 if (expungeonhangup == 1) { 05437 ast_mutex_lock(&vms->lock); 05438 #ifdef HAVE_IMAP_TK2006 05439 if (LEVELUIDPLUS (vms->mailstream)) { 05440 mail_expunge_full(vms->mailstream,NIL,EX_UID); 05441 } else 05442 #endif 05443 mail_expunge(vms->mailstream); 05444 ast_mutex_unlock(&vms->lock); 05445 } 05446 #endif 05447 05448 ast_free(tmp); 05449 return res; 05450 }
| static int load_config | ( | int | reload | ) | [static] |
Definition at line 10377 of file app_voicemail.c.
References adsifdn, adsisec, adsiver, append_mailbox(), apply_options_full(), ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_config_option(), ast_copy_string(), ast_debug, ast_dsp_get_threshold_from_settings(), ast_false(), ast_format_str_reduce(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_LOG_DEBUG, AST_LOG_ERROR, AST_LOG_WARNING, ast_malloc, AST_PTHREADT_NULL, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_unload_realtime(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, 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, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, MINPASSWORD, vm_zone::msg_format, vm_zone::name, ast_variable::name, ast_variable::next, pagerbody, pagerfromstring, pagersubject, populate_defaults(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, 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_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, and VOICEMAIL_CONFIG.
Referenced by handle_voicemail_reload(), load_module(), and reload().
10378 { 10379 struct ast_vm_user *current; 10380 struct ast_config *cfg, *ucfg; 10381 char *cat; 10382 struct ast_variable *var; 10383 const char *val; 10384 char *q, *stringp, *tmp; 10385 int x; 10386 int tmpadsi[4]; 10387 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 10388 10389 ast_unload_realtime("voicemail"); 10390 ast_unload_realtime("voicemail_data"); 10391 10392 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 10393 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) 10394 return 0; 10395 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 10396 cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); 10397 } else { 10398 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 10399 ucfg = ast_config_load("users.conf", config_flags); 10400 } 10401 #ifdef IMAP_STORAGE 10402 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 10403 #endif 10404 /* set audio control prompts */ 10405 strcpy(listen_control_forward_key,DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 10406 strcpy(listen_control_reverse_key,DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 10407 strcpy(listen_control_pause_key,DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 10408 strcpy(listen_control_restart_key,DEFAULT_LISTEN_CONTROL_RESTART_KEY); 10409 strcpy(listen_control_stop_key,DEFAULT_LISTEN_CONTROL_STOP_KEY); 10410 10411 /* Free all the users structure */ 10412 free_vm_users(); 10413 10414 /* Free all the zones structure */ 10415 free_vm_zones(); 10416 10417 AST_LIST_LOCK(&users); 10418 10419 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 10420 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 10421 10422 if (cfg) { 10423 /* General settings */ 10424 10425 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 10426 val = "default"; 10427 ast_copy_string(userscontext, val, sizeof(userscontext)); 10428 /* Attach voice message to mail message ? */ 10429 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 10430 val = "yes"; 10431 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 10432 10433 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 10434 val = "no"; 10435 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 10436 10437 volgain = 0.0; 10438 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 10439 sscanf(val, "%30lf", &volgain); 10440 10441 #ifdef ODBC_STORAGE 10442 strcpy(odbc_database, "asterisk"); 10443 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 10444 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 10445 } 10446 strcpy(odbc_table, "voicemessages"); 10447 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 10448 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 10449 } 10450 #endif 10451 /* Mail command */ 10452 strcpy(mailcmd, SENDMAIL); 10453 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 10454 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 10455 10456 maxsilence = 0; 10457 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 10458 maxsilence = atoi(val); 10459 if (maxsilence > 0) 10460 maxsilence *= 1000; 10461 } 10462 10463 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 10464 maxmsg = MAXMSG; 10465 } else { 10466 maxmsg = atoi(val); 10467 if (maxmsg <= 0) { 10468 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 10469 maxmsg = MAXMSG; 10470 } else if (maxmsg > MAXMSGLIMIT) { 10471 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 10472 maxmsg = MAXMSGLIMIT; 10473 } 10474 } 10475 10476 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 10477 maxdeletedmsg = 0; 10478 } else { 10479 if (sscanf(val, "%30d", &x) == 1) 10480 maxdeletedmsg = x; 10481 else if (ast_true(val)) 10482 maxdeletedmsg = MAXMSG; 10483 else 10484 maxdeletedmsg = 0; 10485 10486 if (maxdeletedmsg < 0) { 10487 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 10488 maxdeletedmsg = MAXMSG; 10489 } else if (maxdeletedmsg > MAXMSGLIMIT) { 10490 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 10491 maxdeletedmsg = MAXMSGLIMIT; 10492 } 10493 } 10494 10495 /* Load date format config for voicemail mail */ 10496 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 10497 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 10498 } 10499 10500 /* External password changing command */ 10501 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 10502 ast_copy_string(ext_pass_cmd,val,sizeof(ext_pass_cmd)); 10503 pwdchange = PWDCHANGE_EXTERNAL; 10504 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 10505 ast_copy_string(ext_pass_cmd,val,sizeof(ext_pass_cmd)); 10506 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 10507 } 10508 10509 /* External password validation command */ 10510 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 10511 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 10512 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 10513 } 10514 10515 #ifdef IMAP_STORAGE 10516 /* IMAP server address */ 10517 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 10518 ast_copy_string(imapserver, val, sizeof(imapserver)); 10519 } else { 10520 ast_copy_string(imapserver,"localhost", sizeof(imapserver)); 10521 } 10522 /* IMAP server port */ 10523 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 10524 ast_copy_string(imapport, val, sizeof(imapport)); 10525 } else { 10526 ast_copy_string(imapport,"143", sizeof(imapport)); 10527 } 10528 /* IMAP server flags */ 10529 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 10530 ast_copy_string(imapflags, val, sizeof(imapflags)); 10531 } 10532 /* IMAP server master username */ 10533 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 10534 ast_copy_string(authuser, val, sizeof(authuser)); 10535 } 10536 /* IMAP server master password */ 10537 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 10538 ast_copy_string(authpassword, val, sizeof(authpassword)); 10539 } 10540 /* Expunge on exit */ 10541 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 10542 if (ast_false(val)) 10543 expungeonhangup = 0; 10544 else 10545 expungeonhangup = 1; 10546 } else { 10547 expungeonhangup = 1; 10548 } 10549 /* IMAP voicemail folder */ 10550 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 10551 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 10552 } else { 10553 ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder)); 10554 } 10555 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 10556 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 10557 } 10558 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 10559 imapgreetings = ast_true(val); 10560 } else { 10561 imapgreetings = 0; 10562 } 10563 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 10564 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 10565 } else { 10566 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 10567 } 10568 10569 /* There is some very unorthodox casting done here. This is due 10570 * to the way c-client handles the argument passed in. It expects a 10571 * void pointer and casts the pointer directly to a long without 10572 * first dereferencing it. */ 10573 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 10574 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 10575 } else { 10576 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 10577 } 10578 10579 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 10580 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 10581 } else { 10582 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 10583 } 10584 10585 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 10586 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 10587 } else { 10588 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 10589 } 10590 10591 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 10592 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 10593 } else { 10594 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 10595 } 10596 10597 /* Increment configuration version */ 10598 imapversion++; 10599 #endif 10600 /* External voicemail notify application */ 10601 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 10602 ast_copy_string(externnotify, val, sizeof(externnotify)); 10603 ast_debug(1, "found externnotify: %s\n", externnotify); 10604 } else { 10605 externnotify[0] = '\0'; 10606 } 10607 10608 /* SMDI voicemail notification */ 10609 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 10610 ast_debug(1, "Enabled SMDI voicemail notification\n"); 10611 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 10612 smdi_iface = ast_smdi_interface_find ? ast_smdi_interface_find(val) : NULL; 10613 } else { 10614 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 10615 smdi_iface = ast_smdi_interface_find ? ast_smdi_interface_find("/dev/ttyS0") : NULL; 10616 } 10617 if (!smdi_iface) { 10618 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 10619 } 10620 } 10621 10622 /* Silence treshold */ 10623 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 10624 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 10625 silencethreshold = atoi(val); 10626 10627 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 10628 val = ASTERISK_USERNAME; 10629 ast_copy_string(serveremail, val, sizeof(serveremail)); 10630 10631 vmmaxsecs = 0; 10632 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 10633 if (sscanf(val, "%30d", &x) == 1) { 10634 vmmaxsecs = x; 10635 } else { 10636 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 10637 } 10638 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 10639 static int maxmessage_deprecate = 0; 10640 if (maxmessage_deprecate == 0) { 10641 maxmessage_deprecate = 1; 10642 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 10643 } 10644 if (sscanf(val, "%30d", &x) == 1) { 10645 vmmaxsecs = x; 10646 } else { 10647 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 10648 } 10649 } 10650 10651 vmminsecs = 0; 10652 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 10653 if (sscanf(val, "%30d", &x) == 1) { 10654 vmminsecs = x; 10655 if (maxsilence / 1000 >= vmminsecs) { 10656 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 10657 } 10658 } else { 10659 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 10660 } 10661 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 10662 static int maxmessage_deprecate = 0; 10663 if (maxmessage_deprecate == 0) { 10664 maxmessage_deprecate = 1; 10665 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 10666 } 10667 if (sscanf(val, "%30d", &x) == 1) { 10668 vmminsecs = x; 10669 if (maxsilence / 1000 >= vmminsecs) { 10670 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 10671 } 10672 } else { 10673 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 10674 } 10675 } 10676 10677 val = ast_variable_retrieve(cfg, "general", "format"); 10678 if (!val) { 10679 val = "wav"; 10680 } else { 10681 tmp = ast_strdupa(val); 10682 val = ast_format_str_reduce(tmp); 10683 if (!val) { 10684 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 10685 val = "wav"; 10686 } 10687 } 10688 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 10689 10690 skipms = 3000; 10691 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 10692 if (sscanf(val, "%30d", &x) == 1) { 10693 maxgreet = x; 10694 } else { 10695 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 10696 } 10697 } 10698 10699 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 10700 if (sscanf(val, "%30d", &x) == 1) { 10701 skipms = x; 10702 } else { 10703 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 10704 } 10705 } 10706 10707 maxlogins = 3; 10708 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 10709 if (sscanf(val, "%30d", &x) == 1) { 10710 maxlogins = x; 10711 } else { 10712 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 10713 } 10714 } 10715 10716 minpassword = MINPASSWORD; 10717 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 10718 if (sscanf(val, "%30d", &x) == 1) { 10719 minpassword = x; 10720 } else { 10721 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 10722 } 10723 } 10724 10725 /* Force new user to record name ? */ 10726 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 10727 val = "no"; 10728 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 10729 10730 /* Force new user to record greetings ? */ 10731 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 10732 val = "no"; 10733 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 10734 10735 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 10736 ast_debug(1, "VM_CID Internal context string: %s\n", val); 10737 stringp = ast_strdupa(val); 10738 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 10739 if (!ast_strlen_zero(stringp)) { 10740 q = strsep(&stringp, ","); 10741 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 10742 q++; 10743 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 10744 ast_debug(1,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 10745 } else { 10746 cidinternalcontexts[x][0] = '\0'; 10747 } 10748 } 10749 } 10750 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 10751 ast_debug(1,"VM Review Option disabled globally\n"); 10752 val = "no"; 10753 } 10754 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 10755 10756 /* Temporary greeting reminder */ 10757 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 10758 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 10759 val = "no"; 10760 } else { 10761 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 10762 } 10763 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 10764 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 10765 ast_debug(1, "VM next message wrap disabled globally\n"); 10766 val = "no"; 10767 } 10768 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 10769 10770 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 10771 ast_debug(1,"VM Operator break disabled globally\n"); 10772 val = "no"; 10773 } 10774 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 10775 10776 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 10777 ast_debug(1,"VM CID Info before msg disabled globally\n"); 10778 val = "no"; 10779 } 10780 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 10781 10782 if (!(val = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){ 10783 ast_debug(1,"Send Voicemail msg disabled globally\n"); 10784 val = "no"; 10785 } 10786 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 10787 10788 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 10789 ast_debug(1,"ENVELOPE before msg enabled globally\n"); 10790 val = "yes"; 10791 } 10792 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 10793 10794 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 10795 ast_debug(1,"Move Heard enabled globally\n"); 10796 val = "yes"; 10797 } 10798 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 10799 10800 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 10801 ast_debug(1,"Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 10802 val = "no"; 10803 } 10804 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 10805 10806 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 10807 ast_debug(1,"Duration info before msg enabled globally\n"); 10808 val = "yes"; 10809 } 10810 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 10811 10812 saydurationminfo = 2; 10813 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 10814 if (sscanf(val, "%30d", &x) == 1) { 10815 saydurationminfo = x; 10816 } else { 10817 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 10818 } 10819 } 10820 10821 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 10822 ast_debug(1,"We are not going to skip to the next msg after save/delete\n"); 10823 val = "no"; 10824 } 10825 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 10826 10827 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 10828 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 10829 ast_debug(1, "found dialout context: %s\n", dialcontext); 10830 } else { 10831 dialcontext[0] = '\0'; 10832 } 10833 10834 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 10835 ast_copy_string(callcontext, val, sizeof(callcontext)); 10836 ast_debug(1, "found callback context: %s\n", callcontext); 10837 } else { 10838 callcontext[0] = '\0'; 10839 } 10840 10841 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 10842 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 10843 ast_debug(1, "found operator context: %s\n", exitcontext); 10844 } else { 10845 exitcontext[0] = '\0'; 10846 } 10847 10848 /* load password sounds configuration */ 10849 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 10850 ast_copy_string(vm_password, val, sizeof(vm_password)); 10851 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 10852 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 10853 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 10854 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 10855 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 10856 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 10857 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 10858 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 10859 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 10860 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 10861 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 10862 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 10863 } 10864 /* load configurable audio prompts */ 10865 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 10866 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 10867 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 10868 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 10869 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 10870 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 10871 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 10872 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 10873 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 10874 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 10875 10876 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 10877 val = "no"; 10878 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 10879 10880 poll_freq = DEFAULT_POLL_FREQ; 10881 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 10882 if (sscanf(val, "%30u", &poll_freq) != 1) { 10883 poll_freq = DEFAULT_POLL_FREQ; 10884 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 10885 } 10886 } 10887 10888 poll_mailboxes = 0; 10889 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 10890 poll_mailboxes = ast_true(val); 10891 10892 if (ucfg) { 10893 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 10894 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 10895 continue; 10896 if ((current = find_or_create(userscontext, cat))) { 10897 populate_defaults(current); 10898 apply_options_full(current, ast_variable_browse(ucfg, cat)); 10899 ast_copy_string(current->context, userscontext, sizeof(current->context)); 10900 } 10901 } 10902 ast_config_destroy(ucfg); 10903 } 10904 cat = ast_category_browse(cfg, NULL); 10905 while (cat) { 10906 if (strcasecmp(cat, "general")) { 10907 var = ast_variable_browse(cfg, cat); 10908 if (strcasecmp(cat, "zonemessages")) { 10909 /* Process mailboxes in this context */ 10910 while (var) { 10911 append_mailbox(cat, var->name, var->value); 10912 var = var->next; 10913 } 10914 } else { 10915 /* Timezones in this context */ 10916 while (var) { 10917 struct vm_zone *z; 10918 if ((z = ast_malloc(sizeof(*z)))) { 10919 char *msg_format, *tzone; 10920 msg_format = ast_strdupa(var->value); 10921 tzone = strsep(&msg_format, "|"); 10922 if (msg_format) { 10923 ast_copy_string(z->name, var->name, sizeof(z->name)); 10924 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 10925 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 10926 AST_LIST_LOCK(&zones); 10927 AST_LIST_INSERT_HEAD(&zones, z, list); 10928 AST_LIST_UNLOCK(&zones); 10929 } else { 10930 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 10931 ast_free(z); 10932 } 10933 } else { 10934 AST_LIST_UNLOCK(&users); 10935 ast_config_destroy(cfg); 10936 return -1; 10937 } 10938 var = var->next; 10939 } 10940 } 10941 } 10942 cat = ast_category_browse(cfg, cat); 10943 } 10944 memset(fromstring, 0, sizeof(fromstring)); 10945 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 10946 strcpy(charset, "ISO-8859-1"); 10947 if (emailbody) { 10948 ast_free(emailbody); 10949 emailbody = NULL; 10950 } 10951 if (emailsubject) { 10952 ast_free(emailsubject); 10953 emailsubject = NULL; 10954 } 10955 if (pagerbody) { 10956 ast_free(pagerbody); 10957 pagerbody = NULL; 10958 } 10959 if (pagersubject) { 10960 ast_free(pagersubject); 10961 pagersubject = NULL; 10962 } 10963 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 10964 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 10965 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 10966 ast_copy_string(fromstring, val, sizeof(fromstring)); 10967 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 10968 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 10969 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 10970 ast_copy_string(charset, val, sizeof(charset)); 10971 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 10972 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 10973 for (x = 0; x < 4; x++) { 10974 memcpy(&adsifdn[x], &tmpadsi[x], 1); 10975 } 10976 } 10977 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 10978 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 10979 for (x = 0; x < 4; x++) { 10980 memcpy(&adsisec[x], &tmpadsi[x], 1); 10981 } 10982 } 10983 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 10984 if (atoi(val)) { 10985 adsiver = atoi(val); 10986 } 10987 } 10988 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 10989 ast_copy_string(zonetag, val, sizeof(zonetag)); 10990 } 10991 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 10992 emailsubject = ast_strdup(val); 10993 } 10994 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 10995 emailbody = substitute_escapes(val); 10996 } 10997 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 10998 pagersubject = ast_strdup(val); 10999 } 11000 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 11001 pagerbody = substitute_escapes(val); 11002 } 11003 AST_LIST_UNLOCK(&users); 11004 ast_config_destroy(cfg); 11005 11006 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 11007 start_poll_thread(); 11008 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 11009 stop_poll_thread();; 11010 11011 return 0; 11012 } else { 11013 AST_LIST_UNLOCK(&users); 11014 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 11015 if (ucfg) 11016 ast_config_destroy(ucfg); 11017 return 0; 11018 } 11019 }
| static int load_module | ( | void | ) | [static] |
Definition at line 11065 of file app_voicemail.c.
References ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_install_vm_functions(), ast_log(), AST_LOG_WARNING, ast_manager_register, ast_realtime_require_field(), ast_register_application, ast_taskprocessor_get(), cli_voicemail, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), inboxcount2(), load_config(), mailbox_exists_acf, manager_list_voicemail_users(), messagecount(), mwi_subscription_tps, RQ_CHAR, RQ_UINTEGER3, sayname(), SENTINEL, vm_box_exists(), vm_exec(), vm_execmain(), and vmauthenticate().
11066 { 11067 int res; 11068 my_umask = umask(0); 11069 umask(my_umask); 11070 11071 /* compute the location of the voicemail spool directory */ 11072 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 11073 11074 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 11075 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 11076 } 11077 11078 if ((res = load_config(0))) 11079 return res; 11080 11081 res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm); 11082 res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain); 11083 res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists); 11084 res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate); 11085 res |= ast_custom_function_register(&mailbox_exists_acf); 11086 res |= ast_manager_register("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users, "List All Voicemail User Information"); 11087 if (res) 11088 return res; 11089 11090 ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry)); 11091 11092 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 11093 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 11094 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 11095 11096 return res; 11097 }
| 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. |
The path is constructed as VM_SPOOL_DIRcontext/ext/folder
Definition at line 1283 of file app_voicemail.c.
Referenced by copy_message(), create_dirpath(), make_email_file(), manager_list_voicemail_users(), notify_new_message(), and prep_email_sub_vars().
01284 { 01285 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01286 }
| 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. | |
| 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. | |
| 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. |
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 3978 of file app_voicemail.c.
References add_email_attachment(), ast_channel_alloc, ast_channel_free(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_localtime(), ast_log(), AST_LOG_WARNING, ast_random(), AST_STATE_DOWN, ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), charset, check_mime(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, ast_vm_user::email, emailbody, emaildateformat, emailsubject, encode_mime_str(), ENDL, fromstring, ast_vm_user::fullname, globalflags, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, pbx_substitute_variables_helper(), prep_email_sub_vars(), ast_channel::priority, quote(), strip_control_and_high(), VM_PBXSKIP, and vmu_tm().
Referenced by sendmail().
03979 { 03980 char date[256]; 03981 char host[MAXHOSTNAMELEN] = ""; 03982 char who[256]; 03983 char bound[256]; 03984 char dur[256]; 03985 struct ast_tm tm; 03986 char enc_cidnum[256] = "", enc_cidname[256] = ""; 03987 char *passdata = NULL, *passdata2; 03988 size_t len_passdata = 0, len_passdata2, tmplen; 03989 char *greeting_attachment; 03990 char filename[256]; 03991 03992 #ifdef IMAP_STORAGE 03993 #define ENDL "\r\n" 03994 #else 03995 #define ENDL "\n" 03996 #endif 03997 03998 /* One alloca for multiple fields */ 03999 len_passdata2 = strlen(vmu->fullname); 04000 if (emailsubject && (tmplen = strlen(emailsubject)) > len_passdata2) { 04001 len_passdata2 = tmplen; 04002 } 04003 if ((tmplen = strlen(fromstring)) > len_passdata2) { 04004 len_passdata2 = tmplen; 04005 } 04006 len_passdata2 = len_passdata2 * 3 + 200; 04007 passdata2 = alloca(len_passdata2); 04008 04009 if (cidnum) { 04010 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04011 } 04012 if (cidname) { 04013 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04014 } 04015 gethostname(host, sizeof(host) - 1); 04016 04017 if (strchr(srcemail, '@')) 04018 ast_copy_string(who, srcemail, sizeof(who)); 04019 else 04020 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04021 04022 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04023 if (greeting_attachment) 04024 *greeting_attachment++ = '\0'; 04025 04026 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04027 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04028 fprintf(p, "Date: %s" ENDL, date); 04029 04030 /* Set date format for voicemail mail */ 04031 ast_strftime(date, sizeof(date), emaildateformat, &tm); 04032 04033 if (!ast_strlen_zero(fromstring)) { 04034 struct ast_channel *ast; 04035 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04036 char *ptr; 04037 memset(passdata2, 0, len_passdata2); 04038 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, passdata2, len_passdata2, category, flag); 04039 pbx_substitute_variables_helper(ast, fromstring, passdata2, len_passdata2); 04040 len_passdata = strlen(passdata2) * 3 + 300; 04041 passdata = alloca(len_passdata); 04042 if (check_mime(passdata2)) { 04043 int first_line = 1; 04044 encode_mime_str(passdata2, passdata, len_passdata, strlen("From: "), strlen(who) + 3); 04045 while ((ptr = strchr(passdata, ' '))) { 04046 *ptr = '\0'; 04047 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", passdata); 04048 first_line = 0; 04049 passdata = ptr + 1; 04050 } 04051 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", passdata, who); 04052 } else { 04053 fprintf(p, "From: %s <%s>" ENDL, quote(passdata2, passdata, len_passdata), who); 04054 } 04055 ast_channel_free(ast); 04056 } else { 04057 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04058 } 04059 } else { 04060 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04061 } 04062 04063 if (check_mime(vmu->fullname)) { 04064 int first_line = 1; 04065 char *ptr; 04066 encode_mime_str(vmu->fullname, passdata2, len_passdata2, strlen("To: "), strlen(vmu->email) + 3); 04067 while ((ptr = strchr(passdata2, ' '))) { 04068 *ptr = '\0'; 04069 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", passdata2); 04070 first_line = 0; 04071 passdata2 = ptr + 1; 04072 } 04073 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", passdata2, vmu->email); 04074 } else { 04075 fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata2), vmu->email); 04076 } 04077 if (!ast_strlen_zero(emailsubject)) { 04078 struct ast_channel *ast; 04079 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04080 int vmlen = strlen(emailsubject) * 3 + 200; 04081 /* Only allocate more space if the previous was not large enough */ 04082 if (vmlen > len_passdata) { 04083 passdata = alloca(vmlen); 04084 len_passdata = vmlen; 04085 } 04086 04087 memset(passdata, 0, len_passdata); 04088 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, len_passdata, category, flag); 04089 pbx_substitute_variables_helper(ast, emailsubject, passdata, len_passdata); 04090 if (check_mime(passdata)) { 04091 int first_line = 1; 04092 char *ptr; 04093 encode_mime_str(passdata, passdata2, len_passdata2, strlen("Subject: "), 0); 04094 while ((ptr = strchr(passdata2, ' '))) { 04095 *ptr = '\0'; 04096 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2); 04097 first_line = 0; 04098 passdata2 = ptr + 1; 04099 } 04100 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2); 04101 } else { 04102 fprintf(p, "Subject: %s" ENDL, passdata); 04103 } 04104 ast_channel_free(ast); 04105 } else { 04106 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04107 } 04108 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04109 if (ast_strlen_zero(flag)) { 04110 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04111 } else { 04112 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04113 } 04114 } else { 04115 if (ast_strlen_zero(flag)) { 04116 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04117 } else { 04118 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04119 } 04120 } 04121 04122 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host); 04123 if (imap) { 04124 /* additional information needed for IMAP searching */ 04125 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04126 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04127 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04128 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04129 #ifdef IMAP_STORAGE 04130 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04131 #else 04132 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04133 #endif 04134 /* flag added for Urgent */ 04135 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04136 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04137 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04138 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04139 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04140 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04141 if (!ast_strlen_zero(category)) { 04142 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04143 } else { 04144 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04145 } 04146 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04147 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04148 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL)); 04149 } 04150 if (!ast_strlen_zero(cidnum)) { 04151 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04152 } 04153 if (!ast_strlen_zero(cidname)) { 04154 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04155 } 04156 fprintf(p, "MIME-Version: 1.0" ENDL); 04157 if (attach_user_voicemail) { 04158 /* Something unique. */ 04159 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random()); 04160 04161 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04162 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04163 fprintf(p, "--%s" ENDL, bound); 04164 } 04165 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04166 if (emailbody) { 04167 struct ast_channel *ast; 04168 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04169 char *passdata; 04170 int vmlen = strlen(emailbody)*3 + 200; 04171 passdata = alloca(vmlen); 04172 memset(passdata, 0, vmlen); 04173 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04174 pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen); 04175 fprintf(p, "%s" ENDL, passdata); 04176 ast_channel_free(ast); 04177 } else 04178 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04179 } else if (msgnum > -1) { 04180 if (strcmp(vmu->mailbox, mailbox)) { 04181 /* Forwarded type */ 04182 struct ast_config *msg_cfg; 04183 const char *v; 04184 int inttime; 04185 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04186 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04187 /* Retrieve info from VM attribute file */ 04188 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04189 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04190 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04191 strcat(fromfile, ".txt"); 04192 } 04193 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04194 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04195 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04196 } 04197 04198 /* You might be tempted to do origdate, except that a) it's in the wrong 04199 * format, and b) it's missing for IMAP recordings. */ 04200 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04201 struct timeval tv = { inttime, }; 04202 struct ast_tm tm; 04203 ast_localtime(&tv, &tm, NULL); 04204 ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm); 04205 } 04206 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04207 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04208 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04209 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04210 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04211 date, origcallerid, origdate); 04212 ast_config_destroy(msg_cfg); 04213 } else { 04214 goto plain_message; 04215 } 04216 } else { 04217 plain_message: 04218 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04219 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04220 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04221 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04222 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04223 } 04224 } else { 04225 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04226 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04227 } 04228 04229 if (imap || attach_user_voicemail) { 04230 if (!ast_strlen_zero(attach2)) { 04231 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04232 ast_debug(5, "creating second attachment filename %s\n", filename); 04233 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04234 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04235 ast_debug(5, "creating attachment filename %s\n", filename); 04236 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04237 } else { 04238 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04239 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04240 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04241 } 04242 } 04243 }
| 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. |
The path is constructed as VM_SPOOL_DIRcontext/ext/folder
Definition at line 1298 of file app_voicemail.c.
Referenced by advanced_options(), close_mailbox(), copy_message(), leave_voicemail(), make_email_file(), notify_new_message(), play_message(), prep_email_sub_vars(), save_to_folder(), vm_execmain(), and vm_forwardoptions().
| static int manager_list_voicemail_users | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Manager list voicemail users command.
Definition at line 10210 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().
10211 { 10212 struct ast_vm_user *vmu = NULL; 10213 const char *id = astman_get_header(m, "ActionID"); 10214 char actionid[128] = ""; 10215 10216 if (!ast_strlen_zero(id)) 10217 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 10218 10219 AST_LIST_LOCK(&users); 10220 10221 if (AST_LIST_EMPTY(&users)) { 10222 astman_send_ack(s, m, "There are no voicemail users currently defined."); 10223 AST_LIST_UNLOCK(&users); 10224 return RESULT_SUCCESS; 10225 } 10226 10227 astman_send_ack(s, m, "Voicemail user list will follow"); 10228 10229 AST_LIST_TRAVERSE(&users, vmu, list) { 10230 char dirname[256]; 10231 10232 #ifdef IMAP_STORAGE 10233 int new, old; 10234 inboxcount(vmu->mailbox, &new, &old); 10235 #endif 10236 10237 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 10238 astman_append(s, 10239 "%s" 10240 "Event: VoicemailUserEntry\r\n" 10241 "VMContext: %s\r\n" 10242 "VoiceMailbox: %s\r\n" 10243 "Fullname: %s\r\n" 10244 "Email: %s\r\n" 10245 "Pager: %s\r\n" 10246 "ServerEmail: %s\r\n" 10247 "MailCommand: %s\r\n" 10248 "Language: %s\r\n" 10249 "TimeZone: %s\r\n" 10250 "Callback: %s\r\n" 10251 "Dialout: %s\r\n" 10252 "UniqueID: %s\r\n" 10253 "ExitContext: %s\r\n" 10254 "SayDurationMinimum: %d\r\n" 10255 "SayEnvelope: %s\r\n" 10256 "SayCID: %s\r\n" 10257 "AttachMessage: %s\r\n" 10258 "AttachmentFormat: %s\r\n" 10259 "DeleteMessage: %s\r\n" 10260 "VolumeGain: %.2f\r\n" 10261 "CanReview: %s\r\n" 10262 "CallOperator: %s\r\n" 10263 "MaxMessageCount: %d\r\n" 10264 "MaxMessageLength: %d\r\n" 10265 "NewMessageCount: %d\r\n" 10266 #ifdef IMAP_STORAGE 10267 "OldMessageCount: %d\r\n" 10268 "IMAPUser: %s\r\n" 10269 #endif 10270 "\r\n", 10271 actionid, 10272 vmu->context, 10273 vmu->mailbox, 10274 vmu->fullname, 10275 vmu->email, 10276 vmu->pager, 10277 vmu->serveremail, 10278 vmu->mailcmd, 10279 vmu->language, 10280 vmu->zonetag, 10281 vmu->callback, 10282 vmu->dialout, 10283 vmu->uniqueid, 10284 vmu->exit, 10285 vmu->saydurationm, 10286 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 10287 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 10288 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 10289 vmu->attachfmt, 10290 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 10291 vmu->volgain, 10292 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 10293 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 10294 vmu->maxmsg, 10295 vmu->maxsecs, 10296 #ifdef IMAP_STORAGE 10297 new, old, vmu->imapuser 10298 #else 10299 count_messages(vmu, dirname) 10300 #endif 10301 ); 10302 } 10303 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 10304 10305 AST_LIST_UNLOCK(&users); 10306 10307 return RESULT_SUCCESS; 10308 }
| static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 10044 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().
10045 { 10046 while (poll_thread_run) { 10047 struct timespec ts = { 0, }; 10048 struct timeval wait; 10049 10050 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 10051 ts.tv_sec = wait.tv_sec; 10052 ts.tv_nsec = wait.tv_usec * 1000; 10053 10054 ast_mutex_lock(&poll_lock); 10055 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 10056 ast_mutex_unlock(&poll_lock); 10057 10058 if (!poll_thread_run) 10059 break; 10060 10061 poll_subscribed_mailboxes(); 10062 } 10063 10064 return NULL; 10065 }
| static const char* mbox | ( | int | id | ) | [static] |
Definition at line 1340 of file app_voicemail.c.
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().
01341 { 01342 static const char *msgs[] = { 01343 #ifdef IMAP_STORAGE 01344 imapfolder, 01345 #else 01346 "INBOX", 01347 #endif 01348 "Old", 01349 "Work", 01350 "Family", 01351 "Friends", 01352 "Cust1", 01353 "Cust2", 01354 "Cust3", 01355 "Cust4", 01356 "Cust5", 01357 "Deleted", 01358 "Urgent" 01359 }; 01360 return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "Unknown"; 01361 }
| static int messagecount | ( | const char * | context, | |
| const char * | mailbox, | |||
| const char * | folder | |||
| ) | [static] |
Definition at line 4749 of file app_voicemail.c.
References __has_voicemail().
Referenced by load_module().
04750 { 04751 return __has_voicemail(context, mailbox, folder, 0); 04752 }
| static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 10067 of file app_voicemail.c.
References ast_free.
Referenced by handle_unsubscribe().
10068 { 10069 ast_free(mwi_sub); 10070 }
| static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 10145 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().
10146 { 10147 struct mwi_sub_task *mwist; 10148 10149 if (ast_event_get_type(event) != AST_EVENT_SUB) 10150 return; 10151 10152 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 10153 return; 10154 10155 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 10156 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 10157 return; 10158 } 10159 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 10160 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 10161 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 10162 10163 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 10164 ast_free(mwist); 10165 } 10166 }
| static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 10129 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().
10130 { 10131 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 10132 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 10133 return; 10134 10135 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 10136 return; 10137 10138 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 10139 *uniqueid = u; 10140 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 10141 ast_free(uniqueid); 10142 } 10143 }
| 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. |
Definition at line 6266 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_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, globalflags, ast_vm_user::mailbox, make_dir(), make_file(), manager_event, 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.
Referenced by copy_message(), and leave_voicemail().
06267 { 06268 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 06269 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 06270 const char *category; 06271 char *myserveremail = serveremail; 06272 06273 ast_channel_lock(chan); 06274 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 06275 category = ast_strdupa(category); 06276 } 06277 ast_channel_unlock(chan); 06278 06279 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX"); 06280 make_file(fn, sizeof(fn), todir, msgnum); 06281 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 06282 06283 if (!ast_strlen_zero(vmu->attachfmt)) { 06284 if (strstr(fmt, vmu->attachfmt)) 06285 fmt = vmu->attachfmt; 06286 else 06287 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); 06288 } 06289 06290 /* Attach only the first format */ 06291 fmt = ast_strdupa(fmt); 06292 stringp = fmt; 06293 strsep(&stringp, "|"); 06294 06295 if (!ast_strlen_zero(vmu->serveremail)) 06296 myserveremail = vmu->serveremail; 06297 06298 if (!ast_strlen_zero(vmu->email)) { 06299 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 06300 if (!attach_user_voicemail) 06301 attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH); 06302 06303 if (attach_user_voicemail) 06304 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 06305 06306 /* XXX possible imap issue, should category be NULL XXX */ 06307 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 06308 06309 if (attach_user_voicemail) 06310 DISPOSE(todir, msgnum); 06311 } 06312 06313 if (!ast_strlen_zero(vmu->pager)) { 06314 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, duration, vmu, category, flag); 06315 } 06316 06317 if (ast_test_flag(vmu, VM_DELETE)) 06318 DELETE(todir, msgnum, fn, vmu); 06319 06320 /* Leave voicemail for someone */ 06321 if (ast_app_has_voicemail(ext_context, NULL)) 06322 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 06323 06324 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 06325 06326 manager_event(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); 06327 run_externnotify(vmu->context, vmu->mailbox, flag); 06328 06329 #ifdef IMAP_STORAGE 06330 vm_delete(fn); /* Delete the file, but not the IMAP message */ 06331 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 06332 vm_imap_delete(NULL, vms->curmsg, vmu); 06333 vms->newmessages--; /* Fix new message count */ 06334 } 06335 #endif 06336 06337 return 0; 06338 }
| static int ochar | ( | struct baseio * | bio, | |
| int | c, | |||
| FILE * | so | |||
| ) | [static] |
utility used by base_encode()
Definition at line 3707 of file app_voicemail.c.
References BASELINELEN, eol, and baseio::linelength.
Referenced by base_encode().
03708 { 03709 if (bio->linelength >= BASELINELEN) { 03710 if (fputs(eol,so) == EOF) 03711 return -1; 03712 03713 bio->linelength= 0; 03714 } 03715 03716 if (putc(((unsigned char)c),so) == EOF) 03717 return -1; 03718 03719 bio->linelength++; 03720 03721 return 1; 03722 }
| static int open_mailbox | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu, | |||
| int | box | |||
| ) | [static] |
Definition at line 7021 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, last_message_index(), vm_state::lastmsg, mbox(), vm_state::username, vm_lock_path(), and vm_state::vmbox.
Referenced by vm_execmain().
07022 { 07023 int count_msg, last_msg; 07024 07025 ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox)); 07026 07027 /* Rename the member vmbox HERE so that we don't try to return before 07028 * we know what's going on. 07029 */ 07030 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07031 07032 /* Faster to make the directory than to check if it exists. */ 07033 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07034 07035 count_msg = count_messages(vmu, vms->curdir); 07036 if (count_msg < 0) 07037 return count_msg; 07038 else 07039 vms->lastmsg = count_msg - 1; 07040 07041 /* 07042 The following test is needed in case sequencing gets messed up. 07043 There appears to be more than one way to mess up sequence, so 07044 we will not try to find all of the root causes--just fix it when 07045 detected. 07046 */ 07047 07048 if (vm_lock_path(vms->curdir)) { 07049 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07050 return -1; 07051 } 07052 07053 last_msg = last_message_index(vmu, vms->curdir); 07054 ast_unlock_path(vms->curdir); 07055 07056 if (last_msg < 0) 07057 return last_msg; 07058 07059 return 0; 07060 }
| static int play_message | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6819 of file app_voicemail.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::heard, vm_state::lastmsg, LOG_WARNING, ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, 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_zh(), and vm_execmain().
06820 { 06821 int res = 0; 06822 char filename[256], *cid; 06823 const char *origtime, *context, *category, *duration, *flag; 06824 struct ast_config *msg_cfg; 06825 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06826 06827 vms->starting = 0; 06828 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 06829 adsi_message(chan, vms); 06830 if (!vms->curmsg) 06831 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 06832 else if (vms->curmsg == vms->lastmsg) 06833 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 06834 06835 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 06836 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 06837 msg_cfg = ast_config_load(filename, config_flags); 06838 if (!msg_cfg) { 06839 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 06840 return 0; 06841 } 06842 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 06843 06844 /* Play the word urgent if we are listening to urgent messages */ 06845 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 06846 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 06847 } 06848 06849 if (!res) { 06850 /* POLISH syntax */ 06851 if (!strncasecmp(chan->language, "pl", 2)) { 06852 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 06853 int ten, one; 06854 char nextmsg[256]; 06855 ten = (vms->curmsg + 1) / 10; 06856 one = (vms->curmsg + 1) % 10; 06857 06858 if (vms->curmsg < 20) { 06859 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 06860 res = wait_file2(chan, vms, nextmsg); 06861 } else { 06862 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 06863 res = wait_file2(chan, vms, nextmsg); 06864 if (one > 0) { 06865 if (!res) { 06866 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 06867 res = wait_file2(chan, vms, nextmsg); 06868 } 06869 } 06870 } 06871 } 06872 if (!res) 06873 res = wait_file2(chan, vms, "vm-message"); 06874 /* HEBREW syntax */ 06875 } else if (!strncasecmp(chan->language, "he", 2)) { 06876 if (!vms->curmsg) { 06877 res = wait_file2(chan, vms, "vm-message"); 06878 res = wait_file2(chan, vms, "vm-first"); 06879 } else if (vms->curmsg == vms->lastmsg) { 06880 res = wait_file2(chan, vms, "vm-message"); 06881 res = wait_file2(chan, vms, "vm-last"); 06882 } else { 06883 res = wait_file2(chan, vms, "vm-message"); 06884 res = wait_file2(chan, vms, "vm-number"); 06885 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 06886 } 06887 } else { 06888 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 06889 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 06890 } else { /* DEFAULT syntax */ 06891 res = wait_file2(chan, vms, "vm-message"); 06892 } 06893 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 06894 if (!res) { 06895 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 06896 } 06897 } 06898 } 06899 } 06900 06901 if (!msg_cfg) { 06902 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 06903 return 0; 06904 } 06905 06906 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 06907 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 06908 DISPOSE(vms->curdir, vms->curmsg); 06909 ast_config_destroy(msg_cfg); 06910 return 0; 06911 } 06912 06913 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 06914 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 06915 category = ast_variable_retrieve(msg_cfg, "message", "category"); 06916 06917 context = ast_variable_retrieve(msg_cfg, "message", "context"); 06918 if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */ 06919 context = ast_variable_retrieve(msg_cfg, "message","macrocontext"); 06920 if (!res) { 06921 res = play_message_category(chan, category); 06922 } 06923 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) 06924 res = play_message_datetime(chan, vmu, origtime, filename); 06925 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) 06926 res = play_message_callerid(chan, vms, cid, context, 0); 06927 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) 06928 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 06929 /* Allow pressing '1' to skip envelope / callerid */ 06930 if (res == '1') 06931 res = 0; 06932 ast_config_destroy(msg_cfg); 06933 06934 if (!res) { 06935 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 06936 vms->heard[vms->curmsg] = 1; 06937 #ifdef IMAP_STORAGE 06938 /*IMAP storage stores any prepended message from a forward 06939 * as a separate file from the rest of the message 06940 */ 06941 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 06942 wait_file(chan, vms, vms->introfn); 06943 } 06944 #endif 06945 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 06946 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 06947 res = 0; 06948 } 06949 } 06950 DISPOSE(vms->curdir, vms->curmsg); 06951 return res; 06952 }
| static int play_message_callerid | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | cid, | |||
| const char * | context, | |||
| int | callback | |||
| ) | [static] |
Definition at line 6705 of file app_voicemail.c.
References ast_callerid_parse(), ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_say_digit_str(), ast_stream_and_wait(), ast_strlen_zero(), ast_verb, cidinternalcontexts, MAX_NUM_CID_CONTEXTS, and wait_file2().
Referenced by advanced_options(), and play_message().
06706 { 06707 int res = 0; 06708 int i; 06709 char *callerid, *name; 06710 char prefile[PATH_MAX] = ""; 06711 06712 06713 /* If voicemail cid is not enabled, or we didn't get cid or context from 06714 * the attribute file, leave now. 06715 * 06716 * TODO Still need to change this so that if this function is called by the 06717 * message envelope (and someone is explicitly requesting to hear the CID), 06718 * it does not check to see if CID is enabled in the config file. 06719 */ 06720 if ((cid == NULL)||(context == NULL)) 06721 return res; 06722 06723 /* Strip off caller ID number from name */ 06724 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 06725 ast_callerid_parse(cid, &name, &callerid); 06726 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 06727 /* Check for internal contexts and only */ 06728 /* say extension when the call didn't come from an internal context in the list */ 06729 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 06730 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 06731 if ((strcmp(cidinternalcontexts[i], context) == 0)) 06732 break; 06733 } 06734 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 06735 if (!res) { 06736 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 06737 if (!ast_strlen_zero(prefile)) { 06738 /* See if we can find a recorded name for this person instead of their extension number */ 06739 if (ast_fileexists(prefile, NULL, NULL) > 0) { 06740 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 06741 if (!callback) 06742 res = wait_file2(chan, vms, "vm-from"); 06743 res = ast_stream_and_wait(chan, prefile, ""); 06744 } else { 06745 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 06746 /* Say "from extension" as one saying to sound smoother */ 06747 if (!callback) 06748 res = wait_file2(chan, vms, "vm-from-extension"); 06749 res = ast_say_digit_str(chan, callerid, "", chan->language); 06750 } 06751 } 06752 } 06753 } else if (!res) { 06754 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 06755 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 06756 if (!callback) 06757 res = wait_file2(chan, vms, "vm-from-phonenumber"); 06758 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 06759 } 06760 } else { 06761 /* Number unknown */ 06762 ast_debug(1, "VM-CID: From an unknown number\n"); 06763 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 06764 res = wait_file2(chan, vms, "vm-unknown-caller"); 06765 } 06766 return res; 06767 }
| static int play_message_category | ( | struct ast_channel * | chan, | |
| const char * | category | |||
| ) | [static] |
Definition at line 6618 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
06619 { 06620 int res = 0; 06621 06622 if (!ast_strlen_zero(category)) 06623 res = ast_play_and_wait(chan, category); 06624 06625 if (res) { 06626 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 06627 res = 0; 06628 } 06629 06630 return res; 06631 }
| static int play_message_datetime | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| const char * | origtime, | |||
| const char * | filename | |||
| ) | [static] |
Definition at line 6633 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_get_time_t(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), AST_LOG_WARNING, ast_say_date_with_format, ast_strlen_zero(), ast_tvnow(), 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().
06634 { 06635 int res = 0; 06636 struct vm_zone *the_zone = NULL; 06637 time_t t; 06638 06639 if (ast_get_time_t(origtime, &t, 0, NULL)) { 06640 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 06641 return 0; 06642 } 06643 06644 /* Does this user have a timezone specified? */ 06645 if (!ast_strlen_zero(vmu->zonetag)) { 06646 /* Find the zone in the list */ 06647 struct vm_zone *z; 06648 AST_LIST_LOCK(&zones); 06649 AST_LIST_TRAVERSE(&zones, z, list) { 06650 if (!strcmp(z->name, vmu->zonetag)) { 06651 the_zone = z; 06652 break; 06653 } 06654 } 06655 AST_LIST_UNLOCK(&zones); 06656 } 06657 06658 /* No internal variable parsing for now, so we'll comment it out for the time being */ 06659 #if 0 06660 /* Set the DIFF_* variables */ 06661 ast_localtime(&t, &time_now, NULL); 06662 tv_now = ast_tvnow(); 06663 ast_localtime(&tv_now, &time_then, NULL); 06664 06665 /* Day difference */ 06666 if (time_now.tm_year == time_then.tm_year) 06667 snprintf(temp,sizeof(temp),"%d",time_now.tm_yday); 06668 else 06669 snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 06670 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 06671 06672 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 06673 #endif 06674 if (the_zone) { 06675 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 06676 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 06677 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 06678 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 06679 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 06680 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 06681 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' 'digits/hours' k 'digits/e' M 'digits/minutes'", NULL); 06682 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 06683 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 06684 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 06685 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 06686 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 06687 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 06688 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 06689 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'digits/pt-de' B 'digits/pt-de' Y 'digits/pt-as' HM ", NULL); 06690 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 06691 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 06692 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 06693 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 06694 } else { 06695 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 06696 } 06697 #if 0 06698 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 06699 #endif 06700 return res; 06701 }
| static int play_message_duration | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| const char * | duration, | |||
| int | minduration | |||
| ) | [static] |
Definition at line 6769 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), num, say_and_wait(), and wait_file2().
Referenced by play_message().
06770 { 06771 int res = 0; 06772 int durationm; 06773 int durations; 06774 /* Verify that we have a duration for the message */ 06775 if (duration == NULL) 06776 return res; 06777 06778 /* Convert from seconds to minutes */ 06779 durations=atoi(duration); 06780 durationm=(durations / 60); 06781 06782 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 06783 06784 if ((!res) && (durationm >= minduration)) { 06785 res = wait_file2(chan, vms, "vm-duration"); 06786 06787 /* POLISH syntax */ 06788 if (!strncasecmp(chan->language, "pl", 2)) { 06789 div_t num = div(durationm, 10); 06790 06791 if (durationm == 1) { 06792 res = ast_play_and_wait(chan, "digits/1z"); 06793 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 06794 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 06795 if (num.rem == 2) { 06796 if (!num.quot) { 06797 res = ast_play_and_wait(chan, "digits/2-ie"); 06798 } else { 06799 res = say_and_wait(chan, durationm - 2 , chan->language); 06800 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 06801 } 06802 } else { 06803 res = say_and_wait(chan, durationm, chan->language); 06804 } 06805 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 06806 } else { 06807 res = say_and_wait(chan, durationm, chan->language); 06808 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 06809 } 06810 /* DEFAULT syntax */ 06811 } else { 06812 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 06813 res = wait_file2(chan, vms, "vm-minutes"); 06814 } 06815 } 06816 return res; 06817 }
| 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, | |||
| const char * | unlockdir, | |||
| signed char | record_gain, | |||
| struct vm_state * | vms, | |||
| char * | flag | |||
| ) | [static] |
Definition at line 11359 of file app_voicemail.c.
References acceptdtmf, ast_channel_setoption(), ast_copy_string(), ast_debug, AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), AST_LOG_WARNING, AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, INTRO, ast_vm_user::mailbox, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.
Referenced by leave_voicemail(), vm_forwardoptions(), vm_newuser(), vm_options(), and vm_tempgreeting().
11362 { 11363 /* Record message & let caller review or re-record it, or set options if applicable */ 11364 int res = 0; 11365 int cmd = 0; 11366 int max_attempts = 3; 11367 int attempts = 0; 11368 int recorded = 0; 11369 int msg_exists = 0; 11370 signed char zero_gain = 0; 11371 char tempfile[PATH_MAX]; 11372 char *acceptdtmf = "#"; 11373 char *canceldtmf = ""; 11374 11375 /* Note that urgent and private are for flagging messages as such in the future */ 11376 11377 /* barf if no pointer passed to store duration in */ 11378 if (duration == NULL) { 11379 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 11380 return -1; 11381 } 11382 11383 if (!outsidecaller) 11384 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 11385 else 11386 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 11387 11388 cmd = '3'; /* Want to start by recording */ 11389 11390 while ((cmd >= 0) && (cmd != 't')) { 11391 switch (cmd) { 11392 case '1': 11393 if (!msg_exists) { 11394 /* In this case, 1 is to record a message */ 11395 cmd = '3'; 11396 break; 11397 } else { 11398 /* Otherwise 1 is to save the existing message */ 11399 ast_verb(3, "Saving message as is\n"); 11400 if (!outsidecaller) 11401 ast_filerename(tempfile, recordfile, NULL); 11402 ast_stream_and_wait(chan, "vm-msgsaved", ""); 11403 if (!outsidecaller) { 11404 /* Saves to IMAP server only if imapgreeting=yes */ 11405 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 11406 DISPOSE(recordfile, -1); 11407 } 11408 cmd = 't'; 11409 return res; 11410 } 11411 case '2': 11412 /* Review */ 11413 ast_verb(3, "Reviewing the message\n"); 11414 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 11415 break; 11416 case '3': 11417 msg_exists = 0; 11418 /* Record */ 11419 if (recorded == 1) 11420 ast_verb(3, "Re-recording the message\n"); 11421 else 11422 ast_verb(3, "Recording the message\n"); 11423 11424 if (recorded && outsidecaller) { 11425 cmd = ast_play_and_wait(chan, INTRO); 11426 cmd = ast_play_and_wait(chan, "beep"); 11427 } 11428 recorded = 1; 11429 /* 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 */ 11430 if (record_gain) 11431 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 11432 if (ast_test_flag(vmu, VM_OPERATOR)) 11433 canceldtmf = "0"; 11434 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 11435 if (record_gain) 11436 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 11437 if (cmd == -1) { 11438 /* User has hung up, no options to give */ 11439 if (!outsidecaller) { 11440 /* user was recording a greeting and they hung up, so let's delete the recording. */ 11441 ast_filedelete(tempfile, NULL); 11442 } 11443 return cmd; 11444 } 11445 if (cmd == '0') { 11446 break; 11447 } else if (cmd == '*') { 11448 break; 11449 #if 0 11450 } else if (vmu->review && (*duration < 5)) { 11451 /* Message is too short */ 11452 ast_verb(3, "Message too short\n"); 11453 cmd = ast_play_and_wait(chan, "vm-tooshort"); 11454 cmd = ast_filedelete(tempfile, NULL); 11455 break; 11456 } else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) { 11457 /* Message is all silence */ 11458 ast_verb(3, "Nothing recorded\n"); 11459 cmd = ast_filedelete(tempfile, NULL); 11460 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 11461 if (!cmd) 11462 cmd = ast_play_and_wait(chan, "vm-speakup"); 11463 break; 11464 #endif 11465 } else { 11466 /* If all is well, a message exists */ 11467 msg_exists = 1; 11468 cmd = 0; 11469 } 11470 break; 11471 case '4': 11472 if (outsidecaller) { /* only mark vm messages */ 11473 /* Mark Urgent */ 11474 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 11475 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 11476 ast_debug(1000, "This message is too urgent!\n"); 11477 res = ast_play_and_wait(chan, "vm-marked-urgent"); 11478 strcpy(flag, "Urgent"); 11479 } else if (flag) { 11480 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 11481 res = ast_play_and_wait(chan, "vm-urgent-removed"); 11482 strcpy(flag, ""); 11483 } else { 11484 ast_play_and_wait(chan, "vm-sorry"); 11485 } 11486 cmd = 0; 11487 } else { 11488 cmd = ast_play_and_wait(chan, "vm-sorry"); 11489 } 11490 break; 11491 case '5': 11492 case '6': 11493 case '7': 11494 case '8': 11495 case '9': 11496 case '*': 11497 case '#': 11498 cmd = ast_play_and_wait(chan, "vm-sorry"); 11499 break; 11500 #if 0 11501 /* XXX Commented out for the moment because of the dangers of deleting 11502 a message while recording (can put the message numbers out of sync) */ 11503 case '*': 11504 /* Cancel recording, delete message, offer to take another message*/ 11505 cmd = ast_play_and_wait(chan, "vm-deleted"); 11506 cmd = ast_filedelete(tempfile, NULL); 11507 if (outsidecaller) { 11508 res = vm_exec(chan, NULL); 11509 return res; 11510 } 11511 else 11512 return 1; 11513 #endif 11514 case '0': 11515 if (!ast_test_flag(vmu, VM_OPERATOR)) { 11516 cmd = ast_play_and_wait(chan, "vm-sorry"); 11517 break; 11518 } 11519 if (msg_exists || recorded) { 11520 cmd = ast_play_and_wait(chan, "vm-saveoper"); 11521 if (!cmd) 11522 cmd = ast_waitfordigit(chan, 3000); 11523 if (cmd == '1') { 11524 ast_play_and_wait(chan, "vm-msgsaved"); 11525 cmd = '0'; 11526 } else if (cmd == '4') { 11527 if (flag) { 11528 ast_play_and_wait(chan, "vm-marked-urgent"); 11529 strcpy(flag, "Urgent"); 11530 } 11531 ast_play_and_wait(chan, "vm-msgsaved"); 11532 cmd = '0'; 11533 } else { 11534 ast_play_and_wait(chan, "vm-deleted"); 11535 DELETE(recordfile, -1, recordfile, vmu); 11536 cmd = '0'; 11537 } 11538 } 11539 return cmd; 11540 default: 11541 /* If the caller is an ouside caller, and the review option is enabled, 11542 allow them to review the message, but let the owner of the box review 11543 their OGM's */ 11544 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 11545 return cmd; 11546 if (msg_exists) { 11547 cmd = ast_play_and_wait(chan, "vm-review"); 11548 if (!cmd && outsidecaller) { 11549 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 11550 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 11551 } else if (flag) { 11552 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 11553 } 11554 } 11555 } else { 11556 cmd = ast_play_and_wait(chan, "vm-torerecord"); 11557 if (!cmd) 11558 cmd = ast_waitfordigit(chan, 600); 11559 } 11560 11561 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 11562 cmd = ast_play_and_wait(chan, "vm-reachoper"); 11563 if (!cmd) 11564 cmd = ast_waitfordigit(chan, 600); 11565 } 11566 #if 0 11567 if (!cmd) 11568 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 11569 #endif 11570 if (!cmd) 11571 cmd = ast_waitfordigit(chan, 6000); 11572 if (!cmd) { 11573 attempts++; 11574 } 11575 if (attempts > max_attempts) { 11576 cmd = 't'; 11577 } 11578 } 11579 } 11580 if (outsidecaller) 11581 ast_play_and_wait(chan, "vm-goodbye"); 11582 if (cmd == 't') 11583 cmd = 0; 11584 return cmd; 11585 }
| static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 10017 of file app_voicemail.c.
References inboxcount2(), mwi_sub::mailbox, mwi_sub::old_new, mwi_sub::old_old, mwi_sub::old_urgent, and queue_mwi_event().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
10018 { 10019 int new = 0, old = 0, urgent = 0; 10020 10021 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 10022 10023 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 10024 mwi_sub->old_urgent = urgent; 10025 mwi_sub->old_new = new; 10026 mwi_sub->old_old = old; 10027 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 10028 } 10029 }
| static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 10031 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().
10032 { 10033 struct mwi_sub *mwi_sub; 10034 10035 AST_RWLIST_RDLOCK(&mwi_subs); 10036 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 10037 if (!ast_strlen_zero(mwi_sub->mailbox)) { 10038 poll_subscribed_mailbox(mwi_sub); 10039 } 10040 } 10041 AST_RWLIST_UNLOCK(&mwi_subs); 10042 }
| 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 759 of file app_voicemail.c.
References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, ast_vm_user::callback, callcontext, dialcontext, ast_vm_user::dialout, ast_vm_user::exit, exitcontext, globalflags, ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::saydurationm, saydurationminfo, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by append_mailbox(), find_user_realtime(), and load_config().
00760 { 00761 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 00762 if (saydurationminfo) 00763 vmu->saydurationm = saydurationminfo; 00764 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 00765 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 00766 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 00767 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 00768 if (vmmaxsecs) 00769 vmu->maxsecs = vmmaxsecs; 00770 if (maxmsg) 00771 vmu->maxmsg = maxmsg; 00772 if (maxdeletedmsg) 00773 vmu->maxdeletedmsg = maxdeletedmsg; 00774 vmu->volgain = volgain; 00775 }
| 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, | |||
| char * | passdata, | |||
| size_t | passdatasize, | |||
| const char * | category, | |||
| const char * | flag | |||
| ) | [static] |
Definition at line 3792 of file app_voicemail.c.
References ast_callerid_merge(), ast_callerid_split(), ast_config_destroy(), ast_config_load, ast_localtime(), ast_log(), ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, emaildateformat, ast_vm_user::fullname, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, and pbx_builtin_setvar_helper().
Referenced by make_email_file(), and sendpage().
03793 { 03794 char callerid[256]; 03795 char fromdir[256], fromfile[256]; 03796 struct ast_config *msg_cfg; 03797 const char *origcallerid, *origtime; 03798 char origcidname[80], origcidnum[80], origdate[80]; 03799 int inttime; 03800 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 03801 03802 /* Prepare variables for substitution in email body and subject */ 03803 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 03804 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 03805 snprintf(passdata, passdatasize, "%d", msgnum); 03806 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata); 03807 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 03808 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 03809 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 03810 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 03811 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 03812 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 03813 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 03814 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 03815 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 03816 03817 /* Retrieve info from VM attribute file */ 03818 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 03819 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 03820 if (strlen(fromfile) < sizeof(fromfile) - 5) { 03821 strcat(fromfile, ".txt"); 03822 } 03823 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 03824 if (option_debug > 0) { 03825 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 03826 } 03827 return; 03828 } 03829 03830 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 03831 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 03832 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 03833 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 03834 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 03835 } 03836 03837 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 03838 struct timeval tv = { inttime, }; 03839 struct ast_tm tm; 03840 ast_localtime(&tv, &tm, NULL); 03841 ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm); 03842 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 03843 } 03844 ast_config_destroy(msg_cfg); 03845 }
| static void queue_mwi_event | ( | const char * | box, | |
| int | urgent, | |||
| int | new, | |||
| int | old | |||
| ) | [static] |
Definition at line 6230 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().
Referenced by append_mailbox(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
06231 { 06232 struct ast_event *event; 06233 char *mailbox, *context; 06234 06235 /* Strip off @default */ 06236 context = mailbox = ast_strdupa(box); 06237 strsep(&context, "@"); 06238 if (ast_strlen_zero(context)) 06239 context = "default"; 06240 06241 if (!(event = ast_event_new(AST_EVENT_MWI, 06242 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 06243 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 06244 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 06245 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 06246 AST_EVENT_IE_END))) { 06247 return; 06248 } 06249 06250 ast_event_queue_and_cache(event); 06251 }
| static char* quote | ( | const char * | from, | |
| char * | to, | |||
| size_t | len | |||
| ) | [static] |
Wraps a character sequence in double quotes, escaping occurences of quotes within the string.
| from | The string to work with. | |
| to | The string to write the modified quoted string. This buffer should be sufficiently larger than the from string, so as to allow it to be expanded by the surrounding quotes and escaping of internal quotes. |
Definition at line 3854 of file app_voicemail.c.
Referenced by make_email_file().
03855 { 03856 char *ptr = to; 03857 *ptr++ = '"'; 03858 for (; ptr < to + len - 1; from++) { 03859 if (*from == '"') 03860 *ptr++ = '\\'; 03861 else if (*from == '\0') 03862 break; 03863 *ptr++ = *from; 03864 } 03865 if (ptr < to + len - 1) 03866 *ptr++ = '"'; 03867 *ptr = '\0'; 03868 return to; 03869 }
| static int reload | ( | void | ) | [static] |
Definition at line 11035 of file app_voicemail.c.
References load_config().
11036 { 11037 return load_config(1); 11038 }
| static void rename_file | ( | char * | sfn, | |
| char * | dfn | |||
| ) | [static] |
Renames a message in a mailbox folder.
| sfn | The path to the mailbox information and data file to be renamed. | |
| dfn | The path for where the message data and information files will be renamed to. |
This method is used by the RENAME macro when mailboxes are stored on the filesystem. (not ODBC and not IMAP).
Definition at line 3472 of file app_voicemail.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
03473 { 03474 char stxt[PATH_MAX]; 03475 char dtxt[PATH_MAX]; 03476 ast_filerename(sfn,dfn,NULL); 03477 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 03478 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 03479 if (ast_check_realtime("voicemail_data")) { 03480 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 03481 } 03482 rename(stxt, dtxt); 03483 }
| 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 1166 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().
01167 { 01168 /* This function could be made to generate one from a database, too */ 01169 struct ast_vm_user *cur; 01170 int res = -1; 01171 AST_LIST_LOCK(&users); 01172 AST_LIST_TRAVERSE(&users, cur, list) { 01173 if ((!context || !strcasecmp(context, cur->context)) && 01174 (!strcasecmp(mailbox, cur->mailbox))) 01175 break; 01176 } 01177 if (cur) { 01178 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01179 res = 0; 01180 } 01181 AST_LIST_UNLOCK(&users); 01182 return res; 01183 }
| static void run_externnotify | ( | char * | context, | |
| char * | extension, | |||
| const char * | flag | |||
| ) | [static] |
Definition at line 4885 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.
Referenced by forward_message(), notify_new_message(), and vm_execmain().
04886 { 04887 char arguments[255]; 04888 char ext_context[256] = ""; 04889 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 04890 struct ast_smdi_mwi_message *mwi_msg; 04891 04892 if (!ast_strlen_zero(context)) 04893 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 04894 else 04895 ast_copy_string(ext_context, extension, sizeof(ext_context)); 04896 04897 if (smdi_iface) { 04898 if (ast_app_has_voicemail(ext_context, NULL)) 04899 ast_smdi_mwi_set(smdi_iface, extension); 04900 else 04901 ast_smdi_mwi_unset(smdi_iface, extension); 04902 04903 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 04904 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 04905 if (!strncmp(mwi_msg->cause, "INV", 3)) 04906 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 04907 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 04908 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 04909 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 04910 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 04911 } else { 04912 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 04913 } 04914 } 04915 04916 if (!ast_strlen_zero(externnotify)) { 04917 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 04918 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 04919 } else { 04920 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 04921 ast_debug(1, "Executing %s\n", arguments); 04922 ast_safe_system(arguments); 04923 } 04924 } 04925 }
| static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
| struct vm_state * | vms, | |||
| int | msg, | |||
| int | box | |||
| ) | [static] |
Definition at line 5459 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().
05460 { 05461 #ifdef IMAP_STORAGE 05462 /* we must use mbox(x) folder names, and copy the message there */ 05463 /* simple. huh? */ 05464 char sequence[10]; 05465 char mailbox[256]; 05466 int res; 05467 05468 /* get the real IMAP message number for this message */ 05469 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 05470 05471 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(box)); 05472 ast_mutex_lock(&vms->lock); 05473 /* if save to Old folder, put in INBOX as read */ 05474 if (box == OLD_FOLDER) { 05475 mail_setflag(vms->mailstream, sequence, "\\Seen"); 05476 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 05477 } else if (box == NEW_FOLDER) { 05478 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 05479 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 05480 } 05481 if (!strcasecmp(mbox(NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 05482 ast_mutex_unlock(&vms->lock); 05483 return 0; 05484 } 05485 /* Create the folder if it don't exist */ 05486 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 05487 ast_debug(5, "Checking if folder exists: %s\n",mailbox); 05488 if (mail_create(vms->mailstream, mailbox) == NIL) 05489 ast_debug(5, "Folder exists.\n"); 05490 else 05491 ast_log(AST_LOG_NOTICE, "Folder %s created!\n",mbox(box)); 05492 res = !mail_copy(vms->mailstream, sequence, (char *)mbox(box)); 05493 ast_mutex_unlock(&vms->lock); 05494 return res; 05495 #else 05496 char *dir = vms->curdir; 05497 char *username = vms->username; 05498 char *context = vmu->context; 05499 char sfn[PATH_MAX]; 05500 char dfn[PATH_MAX]; 05501 char ddir[PATH_MAX]; 05502 const char *dbox = mbox(box); 05503 int x, i; 05504 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 05505 05506 if (vm_lock_path(ddir)) 05507 return ERROR_LOCK_PATH; 05508 05509 x = last_message_index(vmu, ddir) + 1; 05510 05511 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 05512 x--; 05513 for (i = 1; i <= x; i++) { 05514 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 05515 make_file(sfn, sizeof(sfn), ddir, i); 05516 make_file(dfn, sizeof(dfn), ddir, i - 1); 05517 if (EXISTS(ddir, i, sfn, NULL)) { 05518 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 05519 } else 05520 break; 05521 } 05522 } else { 05523 if (x >= vmu->maxmsg) { 05524 ast_unlock_path(ddir); 05525 return -1; 05526 } 05527 } 05528 make_file(sfn, sizeof(sfn), dir, msg); 05529 make_file(dfn, sizeof(dfn), ddir, x); 05530 if (strcmp(sfn, dfn)) { 05531 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 05532 } 05533 ast_unlock_path(ddir); 05534 #endif 05535 return 0; 05536 }
| static int say_and_wait | ( | struct ast_channel * | chan, | |
| int | num, | |||
| const char * | language | |||
| ) | [static] |
Definition at line 5452 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(), and vm_intro_zh().
05453 { 05454 int d; 05455 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 05456 return d; 05457 }
| static int sayname | ( | struct ast_channel * | chan, | |
| const char * | mailbox, | |||
| const char * | context | |||
| ) | [static] |
Definition at line 11021 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, and RETRIEVE.
Referenced by load_module().
11022 { 11023 int res = -1; 11024 char dir[PATH_MAX]; 11025 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 11026 ast_debug(2, "About to try retrieving name file %s\n", dir); 11027 RETRIEVE(dir, -1, mailbox, context); 11028 if (ast_fileexists(dir, NULL, NULL)) { 11029 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 11030 } 11031 DISPOSE(dir, -1); 11032 return res; 11033 }
| 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 4298 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_WARNING, ast_safe_system(), ast_strlen_zero(), ast_test_flag, ast_vm_user::email, globalflags, ast_vm_user::mailbox, make_email_file(), VM_ATTACH, and vm_mkftemp().
Referenced by forward_message(), and notify_new_message().
04299 { 04300 FILE *p=NULL; 04301 char tmp[80] = "/tmp/astmail-XXXXXX"; 04302 char tmp2[256]; 04303 04304 if (vmu && ast_strlen_zero(vmu->email)) { 04305 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04306 return(0); 04307 } 04308 if (!strcmp(format, "wav49")) 04309 format = "WAV"; 04310 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)); 04311 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04312 command hangs */ 04313 if ((p = vm_mkftemp(tmp)) == NULL) { 04314 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04315 return -1; 04316 } else { 04317 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04318 fclose(p); 04319 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04320 ast_safe_system(tmp2); 04321 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04322 } 04323 return 0; 04324 }
| 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 4326 of file app_voicemail.c.
References ast_channel_alloc, ast_channel_free(), ast_copy_string(), ast_debug, ast_log(), AST_LOG_WARNING, ast_safe_system(), AST_STATE_DOWN, ast_strftime(), ast_strlen_zero(), fromstring, MAXHOSTNAMELEN, pagerbody, pagerfromstring, pagersubject, pbx_substitute_variables_helper(), prep_email_sub_vars(), vm_mkftemp(), and vmu_tm().
Referenced by notify_new_message().
04327 { 04328 char date[256]; 04329 char host[MAXHOSTNAMELEN] = ""; 04330 char who[256]; 04331 char dur[PATH_MAX]; 04332 char tmp[80] = "/tmp/astmail-XXXXXX"; 04333 char tmp2[PATH_MAX]; 04334 struct ast_tm tm; 04335 FILE *p; 04336 04337 if ((p = vm_mkftemp(tmp)) == NULL) { 04338 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04339 return -1; 04340 } 04341 gethostname(host, sizeof(host)-1); 04342 if (strchr(srcemail, '@')) 04343 ast_copy_string(who, srcemail, sizeof(who)); 04344 else 04345 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04346 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04347 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04348 fprintf(p, "Date: %s\n", date); 04349 04350 if (*pagerfromstring) { 04351 struct ast_channel *ast; 04352 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04353 char *passdata; 04354 int vmlen = strlen(fromstring)*3 + 200; 04355 passdata = alloca(vmlen); 04356 memset(passdata, 0, vmlen); 04357 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04358 pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen); 04359 fprintf(p, "From: %s <%s>\n", passdata, who); 04360 ast_channel_free(ast); 04361 } else 04362 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04363 } else 04364 fprintf(p, "From: Asterisk PBX <%s>\n", who); 04365 fprintf(p, "To: %s\n", pager); 04366 if (pagersubject) { 04367 struct ast_channel *ast; 04368 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04369 char *passdata; 04370 int vmlen = strlen(pagersubject) * 3 + 200; 04371 passdata = alloca(vmlen); 04372 memset(passdata, 0, vmlen); 04373 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04374 pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen); 04375 fprintf(p, "Subject: %s\n\n", passdata); 04376 ast_channel_free(ast); 04377 } else 04378 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04379 } else { 04380 if (ast_strlen_zero(flag)) { 04381 fprintf(p, "Subject: New VM\n\n"); 04382 } else { 04383 fprintf(p, "Subject: New %s VM\n\n", flag); 04384 } 04385 } 04386 04387 ast_strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm); 04388 if (pagerbody) { 04389 struct ast_channel *ast; 04390 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04391 char *passdata; 04392 int vmlen = strlen(pagerbody) * 3 + 200; 04393 passdata = alloca(vmlen); 04394 memset(passdata, 0, vmlen); 04395 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04396 pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen); 04397 fprintf(p, "%s\n", passdata); 04398 ast_channel_free(ast); 04399 } else 04400 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04401 } else { 04402 fprintf(p, "New %s long %s msg in box %s\n" 04403 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 04404 } 04405 fclose(p); 04406 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04407 ast_safe_system(tmp2); 04408 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 04409 return 0; 04410 }
| static char* show_users_realtime | ( | int | fd, | |
| const char * | context | |||
| ) | [static] |
Definition at line 9815 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().
09816 { 09817 struct ast_config *cfg; 09818 const char *cat = NULL; 09819 09820 if (!(cfg = ast_load_realtime_multientry("voicemail", 09821 "context", context, SENTINEL))) { 09822 return CLI_FAILURE; 09823 } 09824 09825 ast_cli(fd, 09826 "\n" 09827 "=============================================================\n" 09828 "=== Configured Voicemail Users ==============================\n" 09829 "=============================================================\n" 09830 "===\n"); 09831 09832 while ((cat = ast_category_browse(cfg, cat))) { 09833 struct ast_variable *var = NULL; 09834 ast_cli(fd, 09835 "=== Mailbox ...\n" 09836 "===\n"); 09837 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 09838 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 09839 ast_cli(fd, 09840 "===\n" 09841 "=== ---------------------------------------------------------\n" 09842 "===\n"); 09843 } 09844 09845 ast_cli(fd, 09846 "=============================================================\n" 09847 "\n"); 09848 09849 ast_config_destroy(cfg); 09850 09851 return CLI_SUCCESS; 09852 }
| static void start_poll_thread | ( | void | ) | [static] |
Definition at line 10168 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 load_config().
10169 { 10170 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, NULL, 10171 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 10172 AST_EVENT_IE_END); 10173 10174 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, NULL, 10175 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 10176 AST_EVENT_IE_END); 10177 10178 if (mwi_sub_sub) 10179 ast_event_report_subs(mwi_sub_sub); 10180 10181 poll_thread_run = 1; 10182 10183 ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL); 10184 }
| static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 10186 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 load_config(), and unload_module().
10187 { 10188 poll_thread_run = 0; 10189 10190 if (mwi_sub_sub) { 10191 ast_event_unsubscribe(mwi_sub_sub); 10192 mwi_sub_sub = NULL; 10193 } 10194 10195 if (mwi_unsub_sub) { 10196 ast_event_unsubscribe(mwi_unsub_sub); 10197 mwi_unsub_sub = NULL; 10198 } 10199 10200 ast_mutex_lock(&poll_lock); 10201 ast_cond_signal(&poll_cond); 10202 ast_mutex_unlock(&poll_lock); 10203 10204 pthread_join(poll_thread, NULL); 10205 10206 poll_thread = AST_PTHREADT_NULL; 10207 }
| 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 730 of file app_voicemail.c.
Referenced by make_email_file().
| static char* substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 10332 of file app_voicemail.c.
References ast_free, ast_log(), AST_LOG_NOTICE, ast_str_append(), ast_str_create(), ast_strdup, ast_str::str, and ast_str::used.
Referenced by load_config().
10333 { 10334 char *current, *result; 10335 10336 /* Add 16 for fudge factor */ 10337 struct ast_str *str = ast_str_create(strlen(value) + 16); 10338 10339 /* Substitute strings \r, \n, and \t into the appropriate characters */ 10340 for (current = (char *) value; *current; current++) { 10341 if (*current == '\\') { 10342 current++; 10343 if (!*current) { 10344 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 10345 break; 10346 } 10347 switch (*current) { 10348 case 'r': 10349 ast_str_append(&str, 0, "\r"); 10350 break; 10351 case 'n': 10352 #ifdef IMAP_STORAGE 10353 if (!str->used || str->str[str->used - 1] != '\r') { 10354 ast_str_append(&str, 0, "\r"); 10355 } 10356 #endif 10357 ast_str_append(&str, 0, "\n"); 10358 break; 10359 case 't': 10360 ast_str_append(&str, 0, "\t"); 10361 break; 10362 default: 10363 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 10364 break; 10365 } 10366 } else { 10367 ast_str_append(&str, 0, "%c", *current); 10368 } 10369 } 10370 10371 result = ast_strdup(str->str); 10372 ast_free(str); 10373 10374 return result; 10375 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 11040 of file app_voicemail.c.
References ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_manager_unregister(), AST_PTHREADT_NULL, ast_taskprocessor_unreference(), ast_uninstall_vm_functions(), ast_unload_realtime(), ast_unregister_application(), cli_voicemail, free_vm_users(), free_vm_zones(), mailbox_exists_acf, mwi_subscription_tps, and stop_poll_thread().
11041 { 11042 int res; 11043 11044 res = ast_unregister_application(app); 11045 res |= ast_unregister_application(app2); 11046 res |= ast_unregister_application(app3); 11047 res |= ast_unregister_application(app4); 11048 res |= ast_custom_function_unregister(&mailbox_exists_acf); 11049 res |= ast_manager_unregister("VoicemailUsersList"); 11050 ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry)); 11051 ast_uninstall_vm_functions(); 11052 11053 if (poll_thread != AST_PTHREADT_NULL) 11054 stop_poll_thread(); 11055 11056 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 11057 ast_unload_realtime("voicemail"); 11058 ast_unload_realtime("voicemail_data"); 11059 11060 free_vm_users(); 11061 free_vm_zones(); 11062 return res; 11063 }
| 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 8767 of file app_voicemail.c.
References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_debug, ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_verb, ast_waitstream(), ast_channel::cid, ast_callerid::cid_num, find_user(), ast_vm_user::password, and vm_password.
Referenced by vm_execmain(), and vmauthenticate().
08770 { 08771 int useadsi=0, valid=0, logretries=0; 08772 char password[AST_MAX_EXTENSION]="", *passptr; 08773 struct ast_vm_user vmus, *vmu = NULL; 08774 08775 /* If ADSI is supported, setup login screen */ 08776 adsi_begin(chan, &useadsi); 08777 if (!skipuser && useadsi) 08778 adsi_login(chan); 08779 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 08780 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 08781 return -1; 08782 } 08783 08784 /* Authenticate them and get their mailbox/password */ 08785 08786 while (!valid && (logretries < max_logins)) { 08787 /* Prompt for, and read in the username */ 08788 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 08789 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 08790 return -1; 08791 } 08792 if (ast_strlen_zero(mailbox)) { 08793 if (chan->cid.cid_num) { 08794 ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size); 08795 } else { 08796 ast_verb(3,"Username not entered\n"); 08797 return -1; 08798 } 08799 } 08800 if (useadsi) 08801 adsi_password(chan); 08802 08803 if (!ast_strlen_zero(prefix)) { 08804 char fullusername[80] = ""; 08805 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 08806 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 08807 ast_copy_string(mailbox, fullusername, mailbox_size); 08808 } 08809 08810 ast_debug(1, "Before find user for mailbox %s\n",mailbox); 08811 vmu = find_user(&vmus, context, mailbox); 08812 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 08813 /* saved password is blank, so don't bother asking */ 08814 password[0] = '\0'; 08815 } else { 08816 if (ast_streamfile(chan, vm_password, chan->language)) { 08817 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 08818 return -1; 08819 } 08820 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 08821 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 08822 return -1; 08823 } 08824 } 08825 08826 if (vmu) { 08827 passptr = vmu->password; 08828 if (passptr[0] == '-') passptr++; 08829 } 08830 if (vmu && !strcmp(passptr, password)) 08831 valid++; 08832 else { 08833 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 08834 if (!ast_strlen_zero(prefix)) 08835 mailbox[0] = '\0'; 08836 } 08837 logretries++; 08838 if (!valid) { 08839 if (skipuser || logretries >= max_logins) { 08840 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 08841 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 08842 return -1; 08843 } 08844 } else { 08845 if (useadsi) 08846 adsi_login(chan); 08847 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 08848 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 08849 return -1; 08850 } 08851 } 08852 if (ast_waitstream(chan, "")) /* Channel is hung up */ 08853 return -1; 08854 } 08855 } 08856 if (!valid && (logretries >= max_logins)) { 08857 ast_stopstream(chan); 08858 ast_play_and_wait(chan, "vm-goodbye"); 08859 return -1; 08860 } 08861 if (vmu && !skipuser) { 08862 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 08863 } 08864 return 0; 08865 }
| static int vm_box_exists | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 9710 of file app_voicemail.c.
References 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().
09711 { 09712 struct ast_vm_user svm; 09713 char *context, *box; 09714 AST_DECLARE_APP_ARGS(args, 09715 AST_APP_ARG(mbox); 09716 AST_APP_ARG(options); 09717 ); 09718 static int dep_warning = 0; 09719 09720 if (ast_strlen_zero(data)) { 09721 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 09722 return -1; 09723 } 09724 09725 if (!dep_warning) { 09726 dep_warning = 1; 09727 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *)data); 09728 } 09729 09730 box = ast_strdupa(data); 09731 09732 AST_STANDARD_APP_ARGS(args, box); 09733 09734 if (args.options) { 09735 } 09736 09737 if ((context = strchr(args.mbox, '@'))) { 09738 *context = '\0'; 09739 context++; 09740 } 09741 09742 if (find_user(&svm, context, args.mbox)) { 09743 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 09744 } else 09745 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 09746 09747 return 0; 09748 }
| static int vm_browse_messages | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| struct ast_vm_user * | vmu | |||
| ) | [static] |
Top level method to invoke the language variant vm_browse_messages_XX function.
| chan | The channel for the current user. We read the language property from this. | |
| vms | passed into the language-specific vm_browse_messages function. | |
| vmu | passed into the language-specific vm_browse_messages function. |
The method to be invoked is determined by the value of language code property in the user's channel. The default (when unable to match) is to use english.
Definition at line 8748 of file app_voicemail.c.
References vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), and vm_browse_messages_zh().
Referenced by vm_execmain().
08749 { 08750 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 08751 return vm_browse_messages_es(chan, vms, vmu); 08752 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 08753 return vm_browse_messages_gr(chan, vms, vmu); 08754 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 08755 return vm_browse_messages_he(chan, vms, vmu); 08756 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 08757 return vm_browse_messages_it(chan, vms, vmu); 08758 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 08759 return vm_browse_messages_pt(chan, vms, vmu); 08760 } else if (!strncasecmp(chan->language, "zh", 2)) { 08761 return vm_browse_messages_zh(chan, vms, vmu); /* CHINESE (Taiwan) */ 08762 } else { /* Default to English syntax */ 08763 return vm_browse_messages_en(chan, vms, vmu); 08764 } 08765 }
| 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 8611 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().
08612 { 08613 int cmd=0; 08614 08615 if (vms->lastmsg > -1) { 08616 cmd = play_message(chan, vmu, vms); 08617 } else { 08618 cmd = ast_play_and_wait(chan, "vm-youhave"); 08619 if (!cmd) 08620 cmd = ast_play_and_wait(chan, "vm-no"); 08621 if (!cmd) { 08622 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08623 cmd = ast_play_and_wait(chan, vms->fn); 08624 } 08625 if (!cmd) 08626 cmd = ast_play_and_wait(chan, "vm-messages"); 08627 } 08628 return cmd; 08629 }
| 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 8665 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().
08666 { 08667 int cmd=0; 08668 08669 if (vms->lastmsg > -1) { 08670 cmd = play_message(chan, vmu, vms); 08671 } else { 08672 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 08673 if (!cmd) 08674 cmd = ast_play_and_wait(chan, "vm-messages"); 08675 if (!cmd) { 08676 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08677 cmd = ast_play_and_wait(chan, vms->fn); 08678 } 08679 } 08680 return cmd; 08681 }
| 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 8559 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().
08560 { 08561 int cmd=0; 08562 08563 if (vms->lastmsg > -1) { 08564 cmd = play_message(chan, vmu, vms); 08565 } else { 08566 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 08567 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 08568 if (!cmd) { 08569 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 08570 cmd = ast_play_and_wait(chan, vms->fn); 08571 } 08572 if (!cmd) 08573 cmd = ast_play_and_wait(chan, "vm-messages"); 08574 } else { 08575 if (!cmd) 08576 cmd = ast_play_and_wait(chan, "vm-messages"); 08577 if (!cmd) { 08578 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08579 cmd = ast_play_and_wait(chan, vms->fn); 08580 } 08581 } 08582 } 08583 return cmd; 08584 }
| static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| struct ast_vm_user * | vmu | |||
| ) | [static] |
Definition at line 8587 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
08588 { 08589 int cmd = 0; 08590 08591 if (vms->lastmsg > -1) { 08592 cmd = play_message(chan, vmu, vms); 08593 } else { 08594 if (!strcasecmp(vms->fn, "INBOX")) { 08595 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 08596 } else { 08597 cmd = ast_play_and_wait(chan, "vm-nomessages"); 08598 } 08599 } 08600 return cmd; 08601 }
| 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 8639 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().
08640 { 08641 int cmd=0; 08642 08643 if (vms->lastmsg > -1) { 08644 cmd = play_message(chan, vmu, vms); 08645 } else { 08646 cmd = ast_play_and_wait(chan, "vm-no"); 08647 if (!cmd) 08648 cmd = ast_play_and_wait(chan, "vm-message"); 08649 if (!cmd) { 08650 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08651 cmd = ast_play_and_wait(chan, vms->fn); 08652 } 08653 } 08654 return cmd; 08655 }
| 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 8691 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().
08692 { 08693 int cmd=0; 08694 08695 if (vms->lastmsg > -1) { 08696 cmd = play_message(chan, vmu, vms); 08697 } else { 08698 cmd = ast_play_and_wait(chan, "vm-no"); 08699 if (!cmd) { 08700 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08701 cmd = ast_play_and_wait(chan, vms->fn); 08702 } 08703 if (!cmd) 08704 cmd = ast_play_and_wait(chan, "vm-messages"); 08705 } 08706 return cmd; 08707 }
| 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 8717 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().
08718 { 08719 int cmd=0; 08720 08721 if (vms->lastmsg > -1) { 08722 cmd = play_message(chan, vmu, vms); 08723 } else { 08724 cmd = ast_play_and_wait(chan, "vm-you"); 08725 if (!cmd) 08726 cmd = ast_play_and_wait(chan, "vm-haveno"); 08727 if (!cmd) 08728 cmd = ast_play_and_wait(chan, "vm-messages"); 08729 if (!cmd) { 08730 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08731 cmd = ast_play_and_wait(chan, vms->fn); 08732 } 08733 } 08734 return cmd; 08735 }
| 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 1192 of file app_voicemail.c.
References ast_category_browse(), ast_category_get(), ast_config_load, ast_copy_string(), ast_debug, ast_log(), AST_LOG_WARNING, ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), change_password_realtime(), CONFIG_FLAG_WITHCOMMENTS, config_text_file_save(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, reset_user_pw(), var, and VOICEMAIL_CONFIG.
Referenced by vm_newuser(), and vm_options().
01193 { 01194 struct ast_config *cfg=NULL; 01195 struct ast_variable *var=NULL; 01196 struct ast_category *cat=NULL; 01197 char *category=NULL, *value=NULL, *new=NULL; 01198 const char *tmp=NULL; 01199 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01200 if (!change_password_realtime(vmu, newpassword)) 01201 return; 01202 01203 /* check voicemail.conf */ 01204 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags))) { 01205 while ((category = ast_category_browse(cfg, category))) { 01206 if (!strcasecmp(category, vmu->context)) { 01207 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01208 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01209 break; 01210 } 01211 value = strstr(tmp,","); 01212 if (!value) { 01213 ast_log(AST_LOG_WARNING, "variable has bad format.\n"); 01214 break; 01215 } 01216 new = alloca((strlen(value)+strlen(newpassword)+1)); 01217 sprintf(new,"%s%s", newpassword, value); 01218 if (!(cat = ast_category_get(cfg, category))) { 01219 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01220 break; 01221 } 01222 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01223 } 01224 } 01225 /* save the results */ 01226 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01227 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01228 config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01229 } 01230 category = NULL; 01231 var = NULL; 01232 /* check users.conf and update the password stored for the mailbox*/ 01233 /* if no vmsecret entry exists create one. */ 01234 if ((cfg = ast_config_load("users.conf", config_flags))) { 01235 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01236 while ((category = ast_category_browse(cfg, category))) { 01237 ast_debug(4, "users.conf: %s\n", category); 01238 if (!strcasecmp(category, vmu->mailbox)) { 01239 if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) { 01240 ast_debug(3, "looks like we need to make vmsecret!\n"); 01241 var = ast_variable_new("vmsecret", newpassword, ""); 01242 } 01243 new = alloca(strlen(newpassword)+1); 01244 sprintf(new, "%s", newpassword); 01245 if (!(cat = ast_category_get(cfg, category))) { 01246 ast_debug(4, "failed to get category!\n"); 01247 break; 01248 } 01249 if (!var) 01250 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01251 else 01252 ast_variable_append(cat, var); 01253 } 01254 } 01255 /* save the results and clean things up */ 01256 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01257 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01258 config_text_file_save("users.conf", cfg, "AppVoicemail"); 01259 } 01260 }
| static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
| char * | newpassword | |||
| ) | [static] |
Definition at line 1262 of file app_voicemail.c.
References ast_copy_string(), ast_safe_system(), buf, ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().
Referenced by vm_newuser(), and vm_options().
01263 { 01264 char buf[255]; 01265 snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword); 01266 if (!ast_safe_system(buf)) { 01267 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01268 /* Reset the password in memory, too */ 01269 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01270 } 01271 }
| static char* vm_check_password_shell | ( | char * | command, | |
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 886 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().
00887 { 00888 int fds[2], pid = 0; 00889 00890 memset(buf, 0, len); 00891 00892 if (pipe(fds)) { 00893 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 00894 } else { 00895 /* good to go*/ 00896 pid = ast_safe_fork(0); 00897 00898 if (pid < 0) { 00899 /* ok maybe not */ 00900 close(fds[0]); 00901 close(fds[1]); 00902 snprintf(buf, len, "FAILURE: Fork failed"); 00903 } else if (pid) { 00904 /* parent */ 00905 close(fds[1]); 00906 if (read(fds[0], buf, len) < 0) { 00907 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 00908 } 00909 close(fds[0]); 00910 } else { 00911 /* child */ 00912 AST_DECLARE_APP_ARGS(arg, 00913 AST_APP_ARG(v)[20]; 00914 ); 00915 char *mycmd = ast_strdupa(command); 00916 00917 close(fds[0]); 00918 dup2(fds[1], STDOUT_FILENO); 00919 close(fds[1]); 00920 ast_close_fds_above_n(STDOUT_FILENO); 00921 00922 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 00923 00924 execv(arg.v[0], arg.v); 00925 printf("FAILURE: %s", strerror(errno)); 00926 _exit(0); 00927 } 00928 } 00929 return buf; 00930 }
| static int vm_delete | ( | char * | file | ) | [static] |
Removes the voicemail sound and information file.
| file | The path to the sound file. This will be the the folder and message index, without the extension. |
This is used by the DELETE macro when voicemails are stored on the file system.
Definition at line 3649 of file app_voicemail.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
Referenced by copy_message(), and notify_new_message().
03650 { 03651 char *txt; 03652 int txtsize = 0; 03653 03654 txtsize = (strlen(file) + 5)*sizeof(char); 03655 txt = alloca(txtsize); 03656 /* Sprintf here would safe because we alloca'd exactly the right length, 03657 * but trying to eliminate all sprintf's anyhow 03658 */ 03659 if (ast_check_realtime("voicemail_data")) { 03660 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 03661 } 03662 snprintf(txt, txtsize, "%s.txt", file); 03663 unlink(txt); 03664 return ast_filedelete(file, NULL); 03665 }
| static int vm_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 9578 of file app_voicemail.c.
References ast_channel::_state, 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_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, leave_vm_options::exitcontext, leave_voicemail(), 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().
09579 { 09580 int res = 0; 09581 char *tmp; 09582 struct leave_vm_options leave_options; 09583 struct ast_flags flags = { 0 }; 09584 char *opts[OPT_ARG_ARRAY_SIZE]; 09585 AST_DECLARE_APP_ARGS(args, 09586 AST_APP_ARG(argv0); 09587 AST_APP_ARG(argv1); 09588 ); 09589 09590 memset(&leave_options, 0, sizeof(leave_options)); 09591 09592 if (chan->_state != AST_STATE_UP) 09593 ast_answer(chan); 09594 09595 if (!ast_strlen_zero(data)) { 09596 tmp = ast_strdupa(data); 09597 AST_STANDARD_APP_ARGS(args, tmp); 09598 if (args.argc == 2) { 09599 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09600 return -1; 09601 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 09602 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09603 int gain; 09604 09605 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09606 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09607 return -1; 09608 } else { 09609 leave_options.record_gain = (signed char) gain; 09610 } 09611 } 09612 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 09613 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 09614 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 09615 } 09616 } 09617 } else { 09618 char temp[256]; 09619 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 09620 if (res < 0) 09621 return res; 09622 if (ast_strlen_zero(temp)) 09623 return 0; 09624 args.argv0 = ast_strdupa(temp); 09625 } 09626 09627 res = leave_voicemail(chan, args.argv0, &leave_options); 09628 09629 if (res == ERROR_LOCK_PATH) { 09630 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 09631 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 09632 res = 0; 09633 } 09634 09635 return res; 09636 }
| static int vm_execmain | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 8867 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(), ast_adsi_unload_session, ast_answer(), AST_APP_ARG, ast_app_inboxcount2(), ast_app_parse_options(), ast_calloc, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_free, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, ast_mutex_lock(), ast_mutex_unlock(), ast_play_and_wait(), ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_waitfordigit(), ast_vm_user::callback, close_mailbox(), ast_vm_user::context, vm_state::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(), globalflags, has_voicemail(), vm_state::heard, language, ast_vm_user::language, vm_state::lastmsg, ast_vm_user::mailbox, make_file(), manager_event, ast_vm_user::maxmsg, mbox(), NEW_FOLDER, vm_state::newmessages, OLD_FOLDER, vm_state::oldmessages, open_mailbox(), 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().
08868 { 08869 /* XXX This is, admittedly, some pretty horrendous code. For some 08870 reason it just seemed a lot easier to do with GOTO's. I feel 08871 like I'm back in my GWBASIC days. XXX */ 08872 int res=-1; 08873 int cmd=0; 08874 int valid = 0; 08875 char prefixstr[80] =""; 08876 char ext_context[256]=""; 08877 int box; 08878 int useadsi = 0; 08879 int skipuser = 0; 08880 struct vm_state vms; 08881 struct ast_vm_user *vmu = NULL, vmus; 08882 char *context=NULL; 08883 int silentexit = 0; 08884 struct ast_flags flags = { 0 }; 08885 signed char record_gain = 0; 08886 int play_auto = 0; 08887 int play_folder = 0; 08888 int in_urgent = 0; 08889 #ifdef IMAP_STORAGE 08890 int deleted = 0; 08891 #endif 08892 08893 /* Add the vm_state to the active list and keep it active */ 08894 memset(&vms, 0, sizeof(vms)); 08895 08896 vms.lastmsg = -1; 08897 08898 memset(&vmus, 0, sizeof(vmus)); 08899 08900 if (chan->_state != AST_STATE_UP) { 08901 ast_debug(1, "Before ast_answer\n"); 08902 ast_answer(chan); 08903 } 08904 08905 if (!ast_strlen_zero(data)) { 08906 char *opts[OPT_ARG_ARRAY_SIZE]; 08907 char *parse; 08908 AST_DECLARE_APP_ARGS(args, 08909 AST_APP_ARG(argv0); 08910 AST_APP_ARG(argv1); 08911 ); 08912 08913 parse = ast_strdupa(data); 08914 08915 AST_STANDARD_APP_ARGS(args, parse); 08916 08917 if (args.argc == 2) { 08918 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 08919 return -1; 08920 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 08921 int gain; 08922 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 08923 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 08924 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 08925 return -1; 08926 } else { 08927 record_gain = (signed char) gain; 08928 } 08929 } else { 08930 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 08931 } 08932 } 08933 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 08934 play_auto = 1; 08935 if (opts[OPT_ARG_PLAYFOLDER]) { 08936 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 08937 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]); 08938 } 08939 } else { 08940 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 08941 } 08942 if ( play_folder > 9 || play_folder < 0) { 08943 ast_log(AST_LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder); 08944 play_folder = 0; 08945 } 08946 } 08947 } else { 08948 /* old style options parsing */ 08949 while (*(args.argv0)) { 08950 if (*(args.argv0) == 's') 08951 ast_set_flag(&flags, OPT_SILENT); 08952 else if (*(args.argv0) == 'p') 08953 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 08954 else 08955 break; 08956 (args.argv0)++; 08957 } 08958 08959 } 08960 08961 valid = ast_test_flag(&flags, OPT_SILENT); 08962 08963 if ((context = strchr(args.argv0, '@'))) 08964 *context++ = '\0'; 08965 08966 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 08967 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 08968 else 08969 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 08970 08971 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 08972 skipuser++; 08973 else 08974 valid = 0; 08975 } 08976 08977 if (!valid) 08978 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 08979 08980 ast_debug(1, "After vm_authenticate\n"); 08981 if (!res) { 08982 valid = 1; 08983 if (!skipuser) 08984 vmu = &vmus; 08985 } else { 08986 res = 0; 08987 } 08988 08989 /* If ADSI is supported, setup login screen */ 08990 adsi_begin(chan, &useadsi); 08991 08992 if (!valid) { 08993 goto out; 08994 } 08995 08996 #ifdef IMAP_STORAGE 08997 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 08998 pthread_setspecific(ts_vmstate.key, &vms); 08999 09000 vms.interactive = 1; 09001 vms.updated = 1; 09002 if (vmu) 09003 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 09004 vmstate_insert(&vms); 09005 init_vm_state(&vms); 09006 #endif 09007 if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) { 09008 ast_log(AST_LOG_ERROR, "Could not allocate memory for deleted message storage!\n"); 09009 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 09010 return -1; 09011 } 09012 if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) { 09013 ast_log(AST_LOG_ERROR, "Could not allocate memory for heard message storage!\n"); 09014 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 09015 return -1; 09016 } 09017 09018 /* Set language from config to override channel language */ 09019 if (!ast_strlen_zero(vmu->language)) 09020 ast_string_field_set(chan, language, vmu->language); 09021 09022 /* Retrieve urgent, old and new message counts */ 09023 ast_debug(1, "Before open_mailbox\n"); 09024 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 09025 if (res == ERROR_LOCK_PATH) 09026 goto out; 09027 vms.oldmessages = vms.lastmsg + 1; 09028 ast_debug(1, "Number of old messages: %d\n",vms.oldmessages); 09029 /* check INBOX */ 09030 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09031 if (res == ERROR_LOCK_PATH) 09032 goto out; 09033 vms.newmessages = vms.lastmsg + 1; 09034 ast_debug(1, "Number of new messages: %d\n",vms.newmessages); 09035 /* Start in Urgent */ 09036 in_urgent = 1; 09037 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 09038 if (res == ERROR_LOCK_PATH) 09039 goto out; 09040 vms.urgentmessages = vms.lastmsg + 1; 09041 ast_debug(1, "Number of urgent messages: %d\n",vms.urgentmessages); 09042 09043 /* Select proper mailbox FIRST!! */ 09044 if (play_auto) { 09045 if (vms.urgentmessages) { 09046 in_urgent = 1; 09047 res = open_mailbox(&vms, vmu, 11); 09048 } else { 09049 in_urgent = 0; 09050 res = open_mailbox(&vms, vmu, play_folder); 09051 } 09052 if (res == ERROR_LOCK_PATH) 09053 goto out; 09054 09055 /* If there are no new messages, inform the user and hangup */ 09056 if (vms.lastmsg == -1) { 09057 in_urgent = 0; 09058 cmd = vm_browse_messages(chan, &vms, vmu); 09059 res = 0; 09060 goto out; 09061 } 09062 } else { 09063 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 09064 /* If we only have old messages start here */ 09065 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 09066 in_urgent = 0; 09067 play_folder = 1; 09068 if (res == ERROR_LOCK_PATH) 09069 goto out; 09070 } else if (!vms.urgentmessages && vms.newmessages) { 09071 /* If we have new messages but none are urgent */ 09072 in_urgent = 0; 09073 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09074 if (res == ERROR_LOCK_PATH) 09075 goto out; 09076 } 09077 } 09078 09079 if (useadsi) 09080 adsi_status(chan, &vms); 09081 res = 0; 09082 09083 /* Check to see if this is a new user */ 09084 if (!strcasecmp(vmu->mailbox, vmu->password) && 09085 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 09086 if (ast_play_and_wait(chan, "vm-newuser") == -1) 09087 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 09088 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 09089 if ((cmd == 't') || (cmd == '#')) { 09090 /* Timeout */ 09091 res = 0; 09092 goto out; 09093 } else if (cmd < 0) { 09094 /* Hangup */ 09095 res = -1; 09096 goto out; 09097 } 09098 } 09099 #ifdef IMAP_STORAGE 09100 ast_debug(3, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit); 09101 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 09102 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 09103 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09104 } 09105 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg); 09106 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 09107 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 09108 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09109 } 09110 #endif 09111 if (play_auto) { 09112 cmd = '1'; 09113 } else { 09114 cmd = vm_intro(chan, vmu, &vms); 09115 } 09116 09117 vms.repeats = 0; 09118 vms.starting = 1; 09119 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09120 /* Run main menu */ 09121 switch (cmd) { 09122 case '1': /* First message */ 09123 vms.curmsg = 0; 09124 /* Fall through */ 09125 case '5': /* Play current message */ 09126 cmd = vm_browse_messages(chan, &vms, vmu); 09127 break; 09128 case '2': /* Change folders */ 09129 if (useadsi) 09130 adsi_folders(chan, 0, "Change to folder..."); 09131 cmd = get_folder2(chan, "vm-changeto", 0); 09132 if (cmd == '#') { 09133 cmd = 0; 09134 } else if (cmd > 0) { 09135 cmd = cmd - '0'; 09136 res = close_mailbox(&vms, vmu); 09137 if (res == ERROR_LOCK_PATH) 09138 goto out; 09139 /* If folder is not urgent, set in_urgent to zero! */ 09140 if (cmd != 11) in_urgent = 0; 09141 res = open_mailbox(&vms, vmu, cmd); 09142 if (res == ERROR_LOCK_PATH) 09143 goto out; 09144 play_folder = cmd; 09145 cmd = 0; 09146 } 09147 if (useadsi) 09148 adsi_status2(chan, &vms); 09149 09150 if (!cmd) 09151 cmd = vm_play_folder_name(chan, vms.vmbox); 09152 09153 vms.starting = 1; 09154 break; 09155 case '3': /* Advanced options */ 09156 cmd = 0; 09157 vms.repeats = 0; 09158 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09159 switch (cmd) { 09160 case '1': /* Reply */ 09161 if (vms.lastmsg > -1 && !vms.starting) { 09162 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 09163 if (cmd == ERROR_LOCK_PATH) { 09164 res = cmd; 09165 goto out; 09166 } 09167 } else 09168 cmd = ast_play_and_wait(chan, "vm-sorry"); 09169 cmd = 't'; 09170 break; 09171 case '2': /* Callback */ 09172 if (!vms.starting) 09173 ast_verb(3, "Callback Requested\n"); 09174 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 09175 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 09176 if (cmd == 9) { 09177 silentexit = 1; 09178 goto out; 09179 } else if (cmd == ERROR_LOCK_PATH) { 09180 res = cmd; 09181 goto out; 09182 } 09183 } else 09184 cmd = ast_play_and_wait(chan, "vm-sorry"); 09185 cmd = 't'; 09186 break; 09187 case '3': /* Envelope */ 09188 if (vms.lastmsg > -1 && !vms.starting) { 09189 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 09190 if (cmd == ERROR_LOCK_PATH) { 09191 res = cmd; 09192 goto out; 09193 } 09194 } else 09195 cmd = ast_play_and_wait(chan, "vm-sorry"); 09196 cmd = 't'; 09197 break; 09198 case '4': /* Dialout */ 09199 if (!ast_strlen_zero(vmu->dialout)) { 09200 cmd = dialout(chan, vmu, NULL, vmu->dialout); 09201 if (cmd == 9) { 09202 silentexit = 1; 09203 goto out; 09204 } 09205 } else 09206 cmd = ast_play_and_wait(chan, "vm-sorry"); 09207 cmd = 't'; 09208 break; 09209 09210 case '5': /* Leave VoiceMail */ 09211 if (ast_test_flag(vmu, VM_SVMAIL)) { 09212 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 09213 if (cmd == ERROR_LOCK_PATH) { 09214 res = cmd; 09215 ast_log(AST_LOG_WARNING, "forward_message failed to lock path.\n"); 09216 goto out; 09217 } 09218 } else 09219 cmd = ast_play_and_wait(chan,"vm-sorry"); 09220 cmd='t'; 09221 break; 09222 09223 case '*': /* Return to main menu */ 09224 cmd = 't'; 09225 break; 09226 09227 default: 09228 cmd = 0; 09229 if (!vms.starting) { 09230 cmd = ast_play_and_wait(chan, "vm-toreply"); 09231 } 09232 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 09233 cmd = ast_play_and_wait(chan, "vm-tocallback"); 09234 } 09235 if (!cmd && !vms.starting) { 09236 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 09237 } 09238 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 09239 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 09240 } 09241 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) 09242 cmd=ast_play_and_wait(chan, "vm-leavemsg"); 09243 if (!cmd) 09244 cmd = ast_play_and_wait(chan, "vm-starmain"); 09245 if (!cmd) 09246 cmd = ast_waitfordigit(chan,6000); 09247 if (!cmd) 09248 vms.repeats++; 09249 if (vms.repeats > 3) 09250 cmd = 't'; 09251 } 09252 } 09253 if (cmd == 't') { 09254 cmd = 0; 09255 vms.repeats = 0; 09256 } 09257 break; 09258 case '4': /* Go to the previous message */ 09259 if (vms.curmsg > 0) { 09260 vms.curmsg--; 09261 cmd = play_message(chan, vmu, &vms); 09262 } else { 09263 /* Check if we were listening to new 09264 messages. If so, go to Urgent messages 09265 instead of saying "no more messages" 09266 */ 09267 if (in_urgent == 0 && vms.urgentmessages > 0) { 09268 /* Check for Urgent messages */ 09269 in_urgent = 1; 09270 res = close_mailbox(&vms, vmu); 09271 if (res == ERROR_LOCK_PATH) 09272 goto out; 09273 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 09274 if (res == ERROR_LOCK_PATH) 09275 goto out; 09276 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n",vms.lastmsg + 1); 09277 vms.curmsg = vms.lastmsg; 09278 if (vms.lastmsg < 0) 09279 cmd = ast_play_and_wait(chan, "vm-nomore"); 09280 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09281 vms.curmsg = vms.lastmsg; 09282 cmd = play_message(chan, vmu, &vms); 09283 } else { 09284 cmd = ast_play_and_wait(chan, "vm-nomore"); 09285 } 09286 } 09287 break; 09288 case '6': /* Go to the next message */ 09289 if (vms.curmsg < vms.lastmsg) { 09290 vms.curmsg++; 09291 cmd = play_message(chan, vmu, &vms); 09292 } else { 09293 if (in_urgent && vms.newmessages > 0) { 09294 /* Check if we were listening to urgent 09295 * messages. If so, go to regular new messages 09296 * instead of saying "no more messages" 09297 */ 09298 in_urgent = 0; 09299 res = close_mailbox(&vms, vmu); 09300 if (res == ERROR_LOCK_PATH) 09301 goto out; 09302 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09303 if (res == ERROR_LOCK_PATH) 09304 goto out; 09305 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09306 vms.curmsg = -1; 09307 if (vms.lastmsg < 0) { 09308 cmd = ast_play_and_wait(chan, "vm-nomore"); 09309 } 09310 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09311 vms.curmsg = 0; 09312 cmd = play_message(chan, vmu, &vms); 09313 } else { 09314 cmd = ast_play_and_wait(chan, "vm-nomore"); 09315 } 09316 } 09317 break; 09318 case '7': /* Delete the current message */ 09319 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 09320 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 09321 if (useadsi) 09322 adsi_delete(chan, &vms); 09323 if (vms.deleted[vms.curmsg]) { 09324 if (play_folder == 0) { 09325 if (in_urgent) { 09326 vms.urgentmessages--; 09327 } else { 09328 vms.newmessages--; 09329 } 09330 } 09331 else if (play_folder == 1) 09332 vms.oldmessages--; 09333 cmd = ast_play_and_wait(chan, "vm-deleted"); 09334 } else { 09335 if (play_folder == 0) { 09336 if (in_urgent) { 09337 vms.urgentmessages++; 09338 } else { 09339 vms.newmessages++; 09340 } 09341 } 09342 else if (play_folder == 1) 09343 vms.oldmessages++; 09344 cmd = ast_play_and_wait(chan, "vm-undeleted"); 09345 } 09346 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 09347 if (vms.curmsg < vms.lastmsg) { 09348 vms.curmsg++; 09349 cmd = play_message(chan, vmu, &vms); 09350 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09351 vms.curmsg = 0; 09352 cmd = play_message(chan, vmu, &vms); 09353 } else { 09354 /* Check if we were listening to urgent 09355 messages. If so, go to regular new messages 09356 instead of saying "no more messages" 09357 */ 09358 if (in_urgent == 1) { 09359 /* Check for new messages */ 09360 in_urgent = 0; 09361 res = close_mailbox(&vms, vmu); 09362 if (res == ERROR_LOCK_PATH) 09363 goto out; 09364 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09365 if (res == ERROR_LOCK_PATH) 09366 goto out; 09367 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09368 vms.curmsg = -1; 09369 if (vms.lastmsg < 0) 09370 cmd = ast_play_and_wait(chan, "vm-nomore"); 09371 } else { 09372 cmd = ast_play_and_wait(chan, "vm-nomore"); 09373 } 09374 } 09375 } 09376 } else /* Delete not valid if we haven't selected a message */ 09377 cmd = 0; 09378 #ifdef IMAP_STORAGE 09379 deleted = 1; 09380 #endif 09381 break; 09382 09383 case '8': /* Forward the current messgae */ 09384 if (vms.lastmsg > -1) { 09385 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 09386 if (cmd == ERROR_LOCK_PATH) { 09387 res = cmd; 09388 goto out; 09389 } 09390 } else { 09391 /* Check if we were listening to urgent 09392 messages. If so, go to regular new messages 09393 instead of saying "no more messages" 09394 */ 09395 if (in_urgent == 1 && vms.newmessages > 0) { 09396 /* Check for new messages */ 09397 in_urgent = 0; 09398 res = close_mailbox(&vms, vmu); 09399 if (res == ERROR_LOCK_PATH) 09400 goto out; 09401 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09402 if (res == ERROR_LOCK_PATH) 09403 goto out; 09404 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09405 vms.curmsg = -1; 09406 if (vms.lastmsg < 0) 09407 cmd = ast_play_and_wait(chan, "vm-nomore"); 09408 } else { 09409 cmd = ast_play_and_wait(chan, "vm-nomore"); 09410 } 09411 } 09412 break; 09413 case '9': /* Save message to folder */ 09414 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 09415 /* No message selected */ 09416 cmd = 0; 09417 break; 09418 } 09419 if (useadsi) 09420 adsi_folders(chan, 1, "Save to folder..."); 09421 cmd = get_folder2(chan, "vm-savefolder", 1); 09422 box = 0; /* Shut up compiler */ 09423 if (cmd == '#') { 09424 cmd = 0; 09425 break; 09426 } else if (cmd > 0) { 09427 box = cmd = cmd - '0'; 09428 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 09429 if (cmd == ERROR_LOCK_PATH) { 09430 res = cmd; 09431 goto out; 09432 #ifndef IMAP_STORAGE 09433 } else if (!cmd) { 09434 vms.deleted[vms.curmsg] = 1; 09435 #endif 09436 } else { 09437 vms.deleted[vms.curmsg] = 0; 09438 vms.heard[vms.curmsg] = 0; 09439 } 09440 } 09441 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 09442 if (useadsi) 09443 adsi_message(chan, &vms); 09444 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box)); 09445 if (!cmd) { 09446 cmd = ast_play_and_wait(chan, "vm-message"); 09447 if (!cmd) 09448 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 09449 if (!cmd) 09450 cmd = ast_play_and_wait(chan, "vm-savedto"); 09451 if (!cmd) 09452 cmd = vm_play_folder_name(chan, vms.fn); 09453 } else { 09454 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09455 } 09456 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 09457 if (vms.curmsg < vms.lastmsg) { 09458 vms.curmsg++; 09459 cmd = play_message(chan, vmu, &vms); 09460 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09461 vms.curmsg = 0; 09462 cmd = play_message(chan, vmu, &vms); 09463 } else { 09464 /* Check if we were listening to urgent 09465 messages. If so, go to regular new messages 09466 instead of saying "no more messages" 09467 */ 09468 if (in_urgent == 1 && vms.newmessages > 0) { 09469 /* Check for new messages */ 09470 in_urgent = 0; 09471 res = close_mailbox(&vms, vmu); 09472 if (res == ERROR_LOCK_PATH) 09473 goto out; 09474 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09475 if (res == ERROR_LOCK_PATH) 09476 goto out; 09477 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09478 vms.curmsg = -1; 09479 if (vms.lastmsg < 0) 09480 cmd = ast_play_and_wait(chan, "vm-nomore"); 09481 } else { 09482 cmd = ast_play_and_wait(chan, "vm-nomore"); 09483 } 09484 } 09485 } 09486 break; 09487 case '*': /* Help */ 09488 if (!vms.starting) { 09489 cmd = ast_play_and_wait(chan, "vm-onefor"); 09490 if (!strncasecmp(chan->language, "he", 2)) { 09491 cmd = ast_play_and_wait(chan, "vm-for"); 09492 } 09493 if (!cmd) 09494 cmd = vm_play_folder_name(chan, vms.vmbox); 09495 if (!cmd) 09496 cmd = ast_play_and_wait(chan, "vm-opts"); 09497 if (!cmd) 09498 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 09499 } else 09500 cmd = 0; 09501 break; 09502 case '0': /* Mailbox options */ 09503 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 09504 if (useadsi) 09505 adsi_status(chan, &vms); 09506 break; 09507 default: /* Nothing */ 09508 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 09509 break; 09510 } 09511 } 09512 if ((cmd == 't') || (cmd == '#')) { 09513 /* Timeout */ 09514 res = 0; 09515 } else { 09516 /* Hangup */ 09517 res = -1; 09518 } 09519 09520 out: 09521 if (res > -1) { 09522 ast_stopstream(chan); 09523 adsi_goodbye(chan); 09524 if (valid) { 09525 if (silentexit) 09526 res = ast_play_and_wait(chan, "vm-dialout"); 09527 else 09528 res = ast_play_and_wait(chan, "vm-goodbye"); 09529 if (res > 0) 09530 res = 0; 09531 } 09532 if (useadsi) 09533 ast_adsi_unload_session(chan); 09534 } 09535 if (vmu) 09536 close_mailbox(&vms, vmu); 09537 if (valid) { 09538 int new = 0, old = 0, urgent = 0; 09539 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 09540 manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 09541 /* Urgent flag not passwd to externnotify here */ 09542 run_externnotify(vmu->context, vmu->mailbox, NULL); 09543 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 09544 queue_mwi_event(ext_context, urgent, new, old); 09545 } 09546 #ifdef IMAP_STORAGE 09547 /* expunge message - use UID Expunge if supported on IMAP server*/ 09548 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup); 09549 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 09550 ast_mutex_lock(&vms.lock); 09551 #ifdef HAVE_IMAP_TK2006 09552 if (LEVELUIDPLUS (vms.mailstream)) { 09553 mail_expunge_full(vms.mailstream,NIL,EX_UID); 09554 } else 09555 #endif 09556 mail_expunge(vms.mailstream); 09557 ast_mutex_unlock(&vms.lock); 09558 } 09559 /* before we delete the state, we should copy pertinent info 09560 * back to the persistent model */ 09561 if (vmu) { 09562 vmstate_delete(&vms); 09563 } 09564 #endif 09565 if (vmu) 09566 free_user(vmu); 09567 if (vms.deleted) 09568 ast_free(vms.deleted); 09569 if (vms.heard) 09570 ast_free(vms.heard); 09571 09572 #ifdef IMAP_STORAGE 09573 pthread_setspecific(ts_vmstate.key, NULL); 09574 #endif 09575 return res; 09576 }
| 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 | ||
| vmfmts | ||
| context | ||
| record_gain | ||
| duration | ||
| vms | Presents a prompt for 1 to prepend the current message, 2 to forward the message without prepending, or * to return to the main menu. |
This is invoked from forward_message() when performing a forward operation (option 8 from main menu).
Definition at line 6101 of file app_voicemail.c.
References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load, ast_filecopy(), ast_filedelete(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), CONFIG_FLAG_NOCACHE, config_text_file_save(), INTRO, make_file(), ast_vm_user::maxsecs, and play_record_review().
Referenced by forward_message().
06103 { 06104 #ifdef IMAP_STORAGE 06105 int res; 06106 #endif 06107 int cmd = 0; 06108 int retries = 0, prepend_duration = 0, already_recorded = 0; 06109 char msgfile[PATH_MAX], backup[PATH_MAX]; 06110 char textfile[PATH_MAX]; 06111 struct ast_config *msg_cfg; 06112 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06113 #ifndef IMAP_STORAGE 06114 signed char zero_gain = 0; 06115 #endif 06116 const char *duration_str; 06117 06118 /* Must always populate duration correctly */ 06119 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06120 strcpy(textfile, msgfile); 06121 strcpy(backup, msgfile); 06122 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06123 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06124 06125 if ((msg_cfg = ast_config_load(textfile, config_flags)) && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06126 *duration = atoi(duration_str); 06127 } else { 06128 *duration = 0; 06129 } 06130 06131 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06132 if (cmd) 06133 retries = 0; 06134 switch (cmd) { 06135 case '1': 06136 06137 #ifdef IMAP_STORAGE 06138 /* Record new intro file */ 06139 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06140 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06141 res = ast_play_and_wait(chan, INTRO); 06142 res = ast_play_and_wait(chan, "beep"); 06143 res = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *)duration, NULL, record_gain, vms, flag); 06144 cmd = 't'; 06145 #else 06146 06147 /* prepend a message to the current message, update the metadata and return */ 06148 06149 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06150 strcpy(textfile, msgfile); 06151 strncat(textfile, ".txt", sizeof(textfile) - 1); 06152 *duration = 0; 06153 06154 /* if we can't read the message metadata, stop now */ 06155 if (!msg_cfg) { 06156 cmd = 0; 06157 break; 06158 } 06159 06160 /* Back up the original file, so we can retry the prepend */ 06161 if (already_recorded) 06162 ast_filecopy(backup, msgfile, NULL); 06163 else 06164 ast_filecopy(msgfile, backup, NULL); 06165 already_recorded = 1; 06166 06167 if (record_gain) 06168 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06169 06170 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, 1, silencethreshold, maxsilence); 06171 if (record_gain) 06172 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06173 06174 06175 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06176 *duration = atoi(duration_str); 06177 06178 if (prepend_duration) { 06179 struct ast_category *msg_cat; 06180 /* need enough space for a maximum-length message duration */ 06181 char duration_buf[12]; 06182 06183 *duration += prepend_duration; 06184 msg_cat = ast_category_get(msg_cfg, "message"); 06185 snprintf(duration_buf, 11, "%ld", *duration); 06186 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06187 config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06188 } 06189 } 06190 06191 #endif 06192 break; 06193 case '2': 06194 /* NULL out introfile so we know there is no intro! */ 06195 #ifdef IMAP_STORAGE 06196 *vms->introfn = '\0'; 06197 #endif 06198 cmd = 't'; 06199 break; 06200 case '*': 06201 cmd = '*'; 06202 break; 06203 default: 06204 cmd = ast_play_and_wait(chan,"vm-forwardoptions"); 06205 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06206 if (!cmd) 06207 cmd = ast_play_and_wait(chan,"vm-starmain"); 06208 /* "press star to return to the main menu" */ 06209 if (!cmd) 06210 cmd = ast_waitfordigit(chan,6000); 06211 if (!cmd) 06212 retries++; 06213 if (retries > 3) 06214 cmd = 't'; 06215 } 06216 } 06217 06218 if (msg_cfg) 06219 ast_config_destroy(msg_cfg); 06220 if (already_recorded) 06221 ast_filedelete(backup, NULL); 06222 if (prepend_duration) 06223 *duration = prepend_duration; 06224 06225 if (cmd == 't' || cmd == 'S') 06226 cmd = 0; 06227 return cmd; 06228 }
| 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 8251 of file app_voicemail.c.
References vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
08252 { 08253 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 08254 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 08255 } else { /* Default to ENGLISH */ 08256 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 08257 } 08258 }
| 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 8150 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().
08151 { 08152 int res = 0; 08153 /* Play instructions and wait for new command */ 08154 while (!res) { 08155 if (vms->starting) { 08156 if (vms->lastmsg > -1) { 08157 if (skipadvanced) 08158 res = ast_play_and_wait(chan, "vm-onefor-full"); 08159 else 08160 res = ast_play_and_wait(chan, "vm-onefor"); 08161 if (!res) 08162 res = vm_play_folder_name(chan, vms->vmbox); 08163 } 08164 if (!res) { 08165 if (skipadvanced) 08166 res = ast_play_and_wait(chan, "vm-opts-full"); 08167 else 08168 res = ast_play_and_wait(chan, "vm-opts"); 08169 } 08170 } else { 08171 /* Added for additional help */ 08172 if (skipadvanced) { 08173 res = ast_play_and_wait(chan, "vm-onefor-full"); 08174 if (!res) 08175 res = vm_play_folder_name(chan, vms->vmbox); 08176 res = ast_play_and_wait(chan, "vm-opts-full"); 08177 } 08178 /* Logic: 08179 * If the current message is not the first OR 08180 * if we're listening to the first new message and there are 08181 * also urgent messages, then prompt for navigation to the 08182 * previous message 08183 */ 08184 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 08185 res = ast_play_and_wait(chan, "vm-prev"); 08186 } 08187 if (!res && !skipadvanced) 08188 res = ast_play_and_wait(chan, "vm-advopts"); 08189 if (!res) 08190 res = ast_play_and_wait(chan, "vm-repeat"); 08191 /* Logic: 08192 * If we're not listening to the last message OR 08193 * we're listening to the last urgent message and there are 08194 * also new non-urgent messages, then prompt for navigation 08195 * to the next message 08196 */ 08197 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 08198 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 08199 res = ast_play_and_wait(chan, "vm-next"); 08200 } 08201 if (!res) { 08202 if (!vms->deleted[vms->curmsg]) 08203 res = ast_play_and_wait(chan, "vm-delete"); 08204 else 08205 res = ast_play_and_wait(chan, "vm-undelete"); 08206 if (!res) 08207 res = ast_play_and_wait(chan, "vm-toforward"); 08208 if (!res) 08209 res = ast_play_and_wait(chan, "vm-savemessage"); 08210 } 08211 } 08212 if (!res) { 08213 res = ast_play_and_wait(chan, "vm-helpexit"); 08214 } 08215 if (!res) 08216 res = ast_waitfordigit(chan, 6000); 08217 if (!res) { 08218 vms->repeats++; 08219 if (vms->repeats > 2) { 08220 res = 't'; 08221 } 08222 } 08223 } 08224 return res; 08225 }
| 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 8227 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().
08228 { 08229 int res = 0; 08230 /* Play instructions and wait for new command */ 08231 while (!res) { 08232 if (vms->lastmsg > -1) { 08233 res = ast_play_and_wait(chan, "vm-listen"); 08234 if (!res) 08235 res = vm_play_folder_name(chan, vms->vmbox); 08236 if (!res) 08237 res = ast_play_and_wait(chan, "press"); 08238 if (!res) 08239 res = ast_play_and_wait(chan, "digits/1"); 08240 } 08241 if (!res) 08242 res = ast_play_and_wait(chan, "vm-opts"); 08243 if (!res) { 08244 vms->starting = 0; 08245 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 08246 } 08247 } 08248 return res; 08249 }
| static int vm_intro | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8091 of file app_voicemail.c.
References ast_fileexists(), ast_log(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, DISPOSE, LOG_WARNING, ast_vm_user::mailbox, RETRIEVE, vm_state::username, vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_he(), vm_intro_it(), vm_intro_multilang(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_se(), vm_intro_zh(), and VM_TEMPGREETWARN.
Referenced by vm_execmain().
08092 { 08093 char prefile[256]; 08094 08095 /* Notify the user that the temp greeting is set and give them the option to remove it */ 08096 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08097 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 08098 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08099 if (ast_fileexists(prefile, NULL, NULL) > 0) { 08100 ast_play_and_wait(chan, "vm-tempgreetactive"); 08101 } 08102 DISPOSE(prefile, -1); 08103 } 08104 08105 /* Play voicemail intro - syntax is different for different languages */ 08106 if (0) { 08107 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 08108 return vm_intro_cs(chan, vms); 08109 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 08110 static int deprecation_warning = 0; 08111 if (deprecation_warning++ % 10 == 0) { 08112 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 08113 } 08114 return vm_intro_cs(chan, vms); 08115 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 08116 return vm_intro_de(chan, vms); 08117 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 08118 return vm_intro_es(chan, vms); 08119 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 08120 return vm_intro_fr(chan, vms); 08121 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 08122 return vm_intro_gr(chan, vms); 08123 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 08124 return vm_intro_he(chan, vms); 08125 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 08126 return vm_intro_it(chan, vms); 08127 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 08128 return vm_intro_nl(chan, vms); 08129 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 08130 return vm_intro_no(chan, vms); 08131 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 08132 return vm_intro_pl(chan, vms); 08133 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 08134 return vm_intro_pt_BR(chan, vms); 08135 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 08136 return vm_intro_pt(chan, vms); 08137 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 08138 return vm_intro_multilang(chan, vms, "n"); 08139 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 08140 return vm_intro_se(chan, vms); 08141 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 08142 return vm_intro_multilang(chan, vms, "n"); 08143 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 08144 return vm_intro_zh(chan, vms); 08145 } else { /* Default to ENGLISH */ 08146 return vm_intro_en(chan, vms); 08147 } 08148 }
| static int vm_intro_cs | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7992 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07993 { 07994 int res; 07995 res = ast_play_and_wait(chan, "vm-youhave"); 07996 if (!res) { 07997 if (vms->newmessages) { 07998 if (vms->newmessages == 1) { 07999 res = ast_play_and_wait(chan, "digits/jednu"); 08000 } else { 08001 res = say_and_wait(chan, vms->newmessages, chan->language); 08002 } 08003 if (!res) { 08004 if ((vms->newmessages == 1)) 08005 res = ast_play_and_wait(chan, "vm-novou"); 08006 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08007 res = ast_play_and_wait(chan, "vm-nove"); 08008 if (vms->newmessages > 4) 08009 res = ast_play_and_wait(chan, "vm-novych"); 08010 } 08011 if (vms->oldmessages && !res) 08012 res = ast_play_and_wait(chan, "vm-and"); 08013 else if (!res) { 08014 if ((vms->newmessages == 1)) 08015 res = ast_play_and_wait(chan, "vm-zpravu"); 08016 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08017 res = ast_play_and_wait(chan, "vm-zpravy"); 08018 if (vms->newmessages > 4) 08019 res = ast_play_and_wait(chan, "vm-zprav"); 08020 } 08021 } 08022 if (!res && vms->oldmessages) { 08023 res = say_and_wait(chan, vms->oldmessages, chan->language); 08024 if (!res) { 08025 if ((vms->oldmessages == 1)) 08026 res = ast_play_and_wait(chan, "vm-starou"); 08027 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08028 res = ast_play_and_wait(chan, "vm-stare"); 08029 if (vms->oldmessages > 4) 08030 res = ast_play_and_wait(chan, "vm-starych"); 08031 } 08032 if (!res) { 08033 if ((vms->oldmessages == 1)) 08034 res = ast_play_and_wait(chan, "vm-zpravu"); 08035 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08036 res = ast_play_and_wait(chan, "vm-zpravy"); 08037 if (vms->oldmessages > 4) 08038 res = ast_play_and_wait(chan, "vm-zprav"); 08039 } 08040 } 08041 if (!res) { 08042 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08043 res = ast_play_and_wait(chan, "vm-no"); 08044 if (!res) 08045 res = ast_play_and_wait(chan, "vm-zpravy"); 08046 } 08047 } 08048 } 08049 return res; 08050 }
| static int vm_intro_de | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7688 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07689 { 07690 /* Introduce messages they have */ 07691 int res; 07692 res = ast_play_and_wait(chan, "vm-youhave"); 07693 if (!res) { 07694 if (vms->newmessages) { 07695 if ((vms->newmessages == 1)) 07696 res = ast_play_and_wait(chan, "digits/1F"); 07697 else 07698 res = say_and_wait(chan, vms->newmessages, chan->language); 07699 if (!res) 07700 res = ast_play_and_wait(chan, "vm-INBOX"); 07701 if (vms->oldmessages && !res) 07702 res = ast_play_and_wait(chan, "vm-and"); 07703 else if (!res) { 07704 if ((vms->newmessages == 1)) 07705 res = ast_play_and_wait(chan, "vm-message"); 07706 else 07707 res = ast_play_and_wait(chan, "vm-messages"); 07708 } 07709 07710 } 07711 if (!res && vms->oldmessages) { 07712 if (vms->oldmessages == 1) 07713 res = ast_play_and_wait(chan, "digits/1F"); 07714 else 07715 res = say_and_wait(chan, vms->oldmessages, chan->language); 07716 if (!res) 07717 res = ast_play_and_wait(chan, "vm-Old"); 07718 if (!res) { 07719 if (vms->oldmessages == 1) 07720 res = ast_play_and_wait(chan, "vm-message"); 07721 else 07722 res = ast_play_and_wait(chan, "vm-messages"); 07723 } 07724 } 07725 if (!res) { 07726 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07727 res = ast_play_and_wait(chan, "vm-no"); 07728 if (!res) 07729 res = ast_play_and_wait(chan, "vm-messages"); 07730 } 07731 } 07732 } 07733 return res; 07734 }
| static int vm_intro_en | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7437 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07438 { 07439 int res; 07440 07441 /* Introduce messages they have */ 07442 res = ast_play_and_wait(chan, "vm-youhave"); 07443 if (!res) { 07444 if (vms->urgentmessages) { 07445 res = say_and_wait(chan, vms->urgentmessages, chan->language); 07446 if (!res) 07447 res = ast_play_and_wait(chan, "vm-Urgent"); 07448 if ((vms->oldmessages || vms->newmessages) && !res) { 07449 res = ast_play_and_wait(chan, "vm-and"); 07450 } else if (!res) { 07451 if ((vms->urgentmessages == 1)) 07452 res = ast_play_and_wait(chan, "vm-message"); 07453 else 07454 res = ast_play_and_wait(chan, "vm-messages"); 07455 } 07456 } 07457 if (vms->newmessages) { 07458 res = say_and_wait(chan, vms->newmessages, chan->language); 07459 if (!res) 07460 res = ast_play_and_wait(chan, "vm-INBOX"); 07461 if (vms->oldmessages && !res) 07462 res = ast_play_and_wait(chan, "vm-and"); 07463 else if (!res) { 07464 if ((vms->newmessages == 1)) 07465 res = ast_play_and_wait(chan, "vm-message"); 07466 else 07467 res = ast_play_and_wait(chan, "vm-messages"); 07468 } 07469 07470 } 07471 if (!res && vms->oldmessages) { 07472 res = say_and_wait(chan, vms->oldmessages, chan->language); 07473 if (!res) 07474 res = ast_play_and_wait(chan, "vm-Old"); 07475 if (!res) { 07476 if (vms->oldmessages == 1) 07477 res = ast_play_and_wait(chan, "vm-message"); 07478 else 07479 res = ast_play_and_wait(chan, "vm-messages"); 07480 } 07481 } 07482 if (!res) { 07483 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 07484 res = ast_play_and_wait(chan, "vm-no"); 07485 if (!res) 07486 res = ast_play_and_wait(chan, "vm-messages"); 07487 } 07488 } 07489 } 07490 return res; 07491 }
| static int vm_intro_es | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7737 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07738 { 07739 /* Introduce messages they have */ 07740 int res; 07741 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07742 res = ast_play_and_wait(chan, "vm-youhaveno"); 07743 if (!res) 07744 res = ast_play_and_wait(chan, "vm-messages"); 07745 } else { 07746 res = ast_play_and_wait(chan, "vm-youhave"); 07747 } 07748 if (!res) { 07749 if (vms->newmessages) { 07750 if (!res) { 07751 if ((vms->newmessages == 1)) { 07752 res = ast_play_and_wait(chan, "digits/1M"); 07753 if (!res) 07754 res = ast_play_and_wait(chan, "vm-message"); 07755 if (!res) 07756 res = ast_play_and_wait(chan, "vm-INBOXs"); 07757 } else { 07758 res = say_and_wait(chan, vms->newmessages, chan->language); 07759 if (!res) 07760 res = ast_play_and_wait(chan, "vm-messages"); 07761 if (!res) 07762 res = ast_play_and_wait(chan, "vm-INBOX"); 07763 } 07764 } 07765 if (vms->oldmessages && !res) 07766 res = ast_play_and_wait(chan, "vm-and"); 07767 } 07768 if (vms->oldmessages) { 07769 if (!res) { 07770 if (vms->oldmessages == 1) { 07771 res = ast_play_and_wait(chan, "digits/1M"); 07772 if (!res) 07773 res = ast_play_and_wait(chan, "vm-message"); 07774 if (!res) 07775 res = ast_play_and_wait(chan, "vm-Olds"); 07776 } else { 07777 res = say_and_wait(chan, vms->oldmessages, chan->language); 07778 if (!res) 07779 res = ast_play_and_wait(chan, "vm-messages"); 07780 if (!res) 07781 res = ast_play_and_wait(chan, "vm-Old"); 07782 } 07783 } 07784 } 07785 } 07786 return res; 07787 }
| static int vm_intro_fr | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7835 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07836 { 07837 /* Introduce messages they have */ 07838 int res; 07839 res = ast_play_and_wait(chan, "vm-youhave"); 07840 if (!res) { 07841 if (vms->newmessages) { 07842 res = say_and_wait(chan, vms->newmessages, chan->language); 07843 if (!res) 07844 res = ast_play_and_wait(chan, "vm-INBOX"); 07845 if (vms->oldmessages && !res) 07846 res = ast_play_and_wait(chan, "vm-and"); 07847 else if (!res) { 07848 if ((vms->newmessages == 1)) 07849 res = ast_play_and_wait(chan, "vm-message"); 07850 else 07851 res = ast_play_and_wait(chan, "vm-messages"); 07852 } 07853 07854 } 07855 if (!res && vms->oldmessages) { 07856 res = say_and_wait(chan, vms->oldmessages, chan->language); 07857 if (!res) 07858 res = ast_play_and_wait(chan, "vm-Old"); 07859 if (!res) { 07860 if (vms->oldmessages == 1) 07861 res = ast_play_and_wait(chan, "vm-message"); 07862 else 07863 res = ast_play_and_wait(chan, "vm-messages"); 07864 } 07865 } 07866 if (!res) { 07867 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07868 res = ast_play_and_wait(chan, "vm-no"); 07869 if (!res) 07870 res = ast_play_and_wait(chan, "vm-messages"); 07871 } 07872 } 07873 } 07874 return res; 07875 }
| static int vm_intro_gr | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7236 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
07237 { 07238 int res = 0; 07239 07240 if (vms->newmessages) { 07241 res = ast_play_and_wait(chan, "vm-youhave"); 07242 if (!res) 07243 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 07244 if (!res) { 07245 if ((vms->newmessages == 1)) { 07246 res = ast_play_and_wait(chan, "vm-INBOX"); 07247 if (!res) 07248 res = ast_play_and_wait(chan, "vm-message"); 07249 } else { 07250 res = ast_play_and_wait(chan, "vm-INBOXs"); 07251 if (!res) 07252 res = ast_play_and_wait(chan, "vm-messages"); 07253 } 07254 } 07255 } else if (vms->oldmessages){ 07256 res = ast_play_and_wait(chan, "vm-youhave"); 07257 if (!res) 07258 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 07259 if ((vms->oldmessages == 1)){ 07260 res = ast_play_and_wait(chan, "vm-Old"); 07261 if (!res) 07262 res = ast_play_and_wait(chan, "vm-message"); 07263 } else { 07264 res = ast_play_and_wait(chan, "vm-Olds"); 07265 if (!res) 07266 res = ast_play_and_wait(chan, "vm-messages"); 07267 } 07268 } else if (!vms->oldmessages && !vms->newmessages) 07269 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 07270 return res; 07271 }
| static int vm_intro_he | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7370 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
07371 { 07372 int res = 0; 07373 07374 /* Introduce messages they have */ 07375 if (!res) { 07376 if ((vms->newmessages) || (vms->oldmessages)) { 07377 res = ast_play_and_wait(chan, "vm-youhave"); 07378 } 07379 /* 07380 * The word "shtei" refers to the number 2 in hebrew when performing a count 07381 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 07382 * an element, this is one of them. 07383 */ 07384 if (vms->newmessages) { 07385 if (!res) { 07386 if (vms->newmessages == 1) { 07387 res = ast_play_and_wait(chan, "vm-INBOX1"); 07388 } else { 07389 if (vms->newmessages == 2) { 07390 res = ast_play_and_wait(chan, "vm-shtei"); 07391 } else { 07392 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 07393 } 07394 res = ast_play_and_wait(chan, "vm-INBOX"); 07395 } 07396 } 07397 if (vms->oldmessages && !res) { 07398 res = ast_play_and_wait(chan, "vm-and"); 07399 if (vms->oldmessages == 1) { 07400 res = ast_play_and_wait(chan, "vm-Old1"); 07401 } else { 07402 if (vms->oldmessages == 2) { 07403 res = ast_play_and_wait(chan, "vm-shtei"); 07404 } else { 07405 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 07406 } 07407 res = ast_play_and_wait(chan, "vm-Old"); 07408 } 07409 } 07410 } 07411 if (!res && vms->oldmessages && !vms->newmessages) { 07412 if (!res) { 07413 if (vms->oldmessages == 1) { 07414 res = ast_play_and_wait(chan, "vm-Old1"); 07415 } else { 07416 if (vms->oldmessages == 2) { 07417 res = ast_play_and_wait(chan, "vm-shtei"); 07418 } else { 07419 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 07420 } 07421 res = ast_play_and_wait(chan, "vm-Old"); 07422 } 07423 } 07424 } 07425 if (!res) { 07426 if (!vms->oldmessages && !vms->newmessages) { 07427 if (!res) { 07428 res = ast_play_and_wait(chan, "vm-nomessages"); 07429 } 07430 } 07431 } 07432 } 07433 return res; 07434 }
| static int vm_intro_it | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7494 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07495 { 07496 /* Introduce messages they have */ 07497 int res; 07498 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 07499 res = ast_play_and_wait(chan, "vm-no") || 07500 ast_play_and_wait(chan, "vm-message"); 07501 else 07502 res = ast_play_and_wait(chan, "vm-youhave"); 07503 if (!res && vms->newmessages) { 07504 res = (vms->newmessages == 1) ? 07505 ast_play_and_wait(chan, "digits/un") || 07506 ast_play_and_wait(chan, "vm-nuovo") || 07507 ast_play_and_wait(chan, "vm-message") : 07508 /* 2 or more new messages */ 07509 say_and_wait(chan, vms->newmessages, chan->language) || 07510 ast_play_and_wait(chan, "vm-nuovi") || 07511 ast_play_and_wait(chan, "vm-messages"); 07512 if (!res && vms->oldmessages) 07513 res = ast_play_and_wait(chan, "vm-and"); 07514 } 07515 if (!res && vms->oldmessages) { 07516 res = (vms->oldmessages == 1) ? 07517 ast_play_and_wait(chan, "digits/un") || 07518 ast_play_and_wait(chan, "vm-vecchio") || 07519 ast_play_and_wait(chan, "vm-message") : 07520 /* 2 or more old messages */ 07521 say_and_wait(chan, vms->oldmessages, chan->language) || 07522 ast_play_and_wait(chan, "vm-vecchi") || 07523 ast_play_and_wait(chan, "vm-messages"); 07524 } 07525 return res; 07526 }
| static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| const char | message_gender[] | |||
| ) | [static] |
Definition at line 7330 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_counted_adjective(), ast_say_counted_noun(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
07331 { 07332 int res; 07333 int lastnum = 0; 07334 07335 res = ast_play_and_wait(chan, "vm-youhave"); 07336 07337 if (!res && vms->newmessages) { 07338 lastnum = vms->newmessages; 07339 07340 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 07341 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 07342 } 07343 07344 if (!res && vms->oldmessages) { 07345 res = ast_play_and_wait(chan, "vm-and"); 07346 } 07347 } 07348 07349 if (!res && vms->oldmessages) { 07350 lastnum = vms->oldmessages; 07351 07352 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 07353 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 07354 } 07355 } 07356 07357 if (!res) { 07358 if (lastnum == 0) { 07359 res = ast_play_and_wait(chan, "vm-no"); 07360 } 07361 if (!res) { 07362 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 07363 } 07364 } 07365 07366 return res; 07367 }
| static int vm_intro_nl | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7878 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07879 { 07880 /* Introduce messages they have */ 07881 int res; 07882 res = ast_play_and_wait(chan, "vm-youhave"); 07883 if (!res) { 07884 if (vms->newmessages) { 07885 res = say_and_wait(chan, vms->newmessages, chan->language); 07886 if (!res) { 07887 if (vms->newmessages == 1) 07888 res = ast_play_and_wait(chan, "vm-INBOXs"); 07889 else 07890 res = ast_play_and_wait(chan, "vm-INBOX"); 07891 } 07892 if (vms->oldmessages && !res) 07893 res = ast_play_and_wait(chan, "vm-and"); 07894 else if (!res) { 07895 if ((vms->newmessages == 1)) 07896 res = ast_play_and_wait(chan, "vm-message"); 07897 else 07898 res = ast_play_and_wait(chan, "vm-messages"); 07899 } 07900 07901 } 07902 if (!res && vms->oldmessages) { 07903 res = say_and_wait(chan, vms->oldmessages, chan->language); 07904 if (!res) { 07905 if (vms->oldmessages == 1) 07906 res = ast_play_and_wait(chan, "vm-Olds"); 07907 else 07908 res = ast_play_and_wait(chan, "vm-Old"); 07909 } 07910 if (!res) { 07911 if (vms->oldmessages == 1) 07912 res = ast_play_and_wait(chan, "vm-message"); 07913 else 07914 res = ast_play_and_wait(chan, "vm-messages"); 07915 } 07916 } 07917 if (!res) { 07918 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07919 res = ast_play_and_wait(chan, "vm-no"); 07920 if (!res) 07921 res = ast_play_and_wait(chan, "vm-messages"); 07922 } 07923 } 07924 } 07925 return res; 07926 }
| static int vm_intro_no | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7644 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07645 { 07646 /* Introduce messages they have */ 07647 int res; 07648 07649 res = ast_play_and_wait(chan, "vm-youhave"); 07650 if (res) 07651 return res; 07652 07653 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07654 res = ast_play_and_wait(chan, "vm-no"); 07655 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07656 return res; 07657 } 07658 07659 if (vms->newmessages) { 07660 if ((vms->newmessages == 1)) { 07661 res = ast_play_and_wait(chan, "digits/1"); 07662 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 07663 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07664 } else { 07665 res = say_and_wait(chan, vms->newmessages, chan->language); 07666 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 07667 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07668 } 07669 if (!res && vms->oldmessages) 07670 res = ast_play_and_wait(chan, "vm-and"); 07671 } 07672 if (!res && vms->oldmessages) { 07673 if (vms->oldmessages == 1) { 07674 res = ast_play_and_wait(chan, "digits/1"); 07675 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 07676 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07677 } else { 07678 res = say_and_wait(chan, vms->oldmessages, chan->language); 07679 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 07680 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07681 } 07682 } 07683 07684 return res; 07685 }
| static int vm_intro_pl | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7529 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, num, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
07530 { 07531 /* Introduce messages they have */ 07532 int res; 07533 div_t num; 07534 07535 if (!vms->oldmessages && !vms->newmessages) { 07536 res = ast_play_and_wait(chan, "vm-no"); 07537 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07538 return res; 07539 } else { 07540 res = ast_play_and_wait(chan, "vm-youhave"); 07541 } 07542 07543 if (vms->newmessages) { 07544 num = div(vms->newmessages, 10); 07545 if (vms->newmessages == 1) { 07546 res = ast_play_and_wait(chan, "digits/1-a"); 07547 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 07548 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07549 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07550 if (num.rem == 2) { 07551 if (!num.quot) { 07552 res = ast_play_and_wait(chan, "digits/2-ie"); 07553 } else { 07554 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 07555 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07556 } 07557 } else { 07558 res = say_and_wait(chan, vms->newmessages, chan->language); 07559 } 07560 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 07561 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07562 } else { 07563 res = say_and_wait(chan, vms->newmessages, chan->language); 07564 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 07565 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07566 } 07567 if (!res && vms->oldmessages) 07568 res = ast_play_and_wait(chan, "vm-and"); 07569 } 07570 if (!res && vms->oldmessages) { 07571 num = div(vms->oldmessages, 10); 07572 if (vms->oldmessages == 1) { 07573 res = ast_play_and_wait(chan, "digits/1-a"); 07574 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 07575 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07576 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07577 if (num.rem == 2) { 07578 if (!num.quot) { 07579 res = ast_play_and_wait(chan, "digits/2-ie"); 07580 } else { 07581 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 07582 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07583 } 07584 } else { 07585 res = say_and_wait(chan, vms->oldmessages, chan->language); 07586 } 07587 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 07588 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07589 } else { 07590 res = say_and_wait(chan, vms->oldmessages, chan->language); 07591 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 07592 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07593 } 07594 } 07595 07596 return res; 07597 }
| static int vm_intro_pt | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7929 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
07930 { 07931 /* Introduce messages they have */ 07932 int res; 07933 res = ast_play_and_wait(chan, "vm-youhave"); 07934 if (!res) { 07935 if (vms->newmessages) { 07936 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 07937 if (!res) { 07938 if ((vms->newmessages == 1)) { 07939 res = ast_play_and_wait(chan, "vm-message"); 07940 if (!res) 07941 res = ast_play_and_wait(chan, "vm-INBOXs"); 07942 } else { 07943 res = ast_play_and_wait(chan, "vm-messages"); 07944 if (!res) 07945 res = ast_play_and_wait(chan, "vm-INBOX"); 07946 } 07947 } 07948 if (vms->oldmessages && !res) 07949 res = ast_play_and_wait(chan, "vm-and"); 07950 } 07951 if (!res && vms->oldmessages) { 07952 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 07953 if (!res) { 07954 if (vms->oldmessages == 1) { 07955 res = ast_play_and_wait(chan, "vm-message"); 07956 if (!res) 07957 res = ast_play_and_wait(chan, "vm-Olds"); 07958 } else { 07959 res = ast_play_and_wait(chan, "vm-messages"); 07960 if (!res) 07961 res = ast_play_and_wait(chan, "vm-Old"); 07962 } 07963 } 07964 } 07965 if (!res) { 07966 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07967 res = ast_play_and_wait(chan, "vm-no"); 07968 if (!res) 07969 res = ast_play_and_wait(chan, "vm-messages"); 07970 } 07971 } 07972 } 07973 return res; 07974 }
| static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7790 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
07790 { 07791 /* Introduce messages they have */ 07792 int res; 07793 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07794 res = ast_play_and_wait(chan, "vm-nomessages"); 07795 return res; 07796 } else { 07797 res = ast_play_and_wait(chan, "vm-youhave"); 07798 } 07799 if (vms->newmessages) { 07800 if (!res) 07801 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 07802 if ((vms->newmessages == 1)) { 07803 if (!res) 07804 res = ast_play_and_wait(chan, "vm-message"); 07805 if (!res) 07806 res = ast_play_and_wait(chan, "vm-INBOXs"); 07807 } else { 07808 if (!res) 07809 res = ast_play_and_wait(chan, "vm-messages"); 07810 if (!res) 07811 res = ast_play_and_wait(chan, "vm-INBOX"); 07812 } 07813 if (vms->oldmessages && !res) 07814 res = ast_play_and_wait(chan, "vm-and"); 07815 } 07816 if (vms->oldmessages) { 07817 if (!res) 07818 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 07819 if (vms->oldmessages == 1) { 07820 if (!res) 07821 res = ast_play_and_wait(chan, "vm-message"); 07822 if (!res) 07823 res = ast_play_and_wait(chan, "vm-Olds"); 07824 } else { 07825 if (!res) 07826 res = ast_play_and_wait(chan, "vm-messages"); 07827 if (!res) 07828 res = ast_play_and_wait(chan, "vm-Old"); 07829 } 07830 } 07831 return res; 07832 }
| static int vm_intro_se | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7600 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07601 { 07602 /* Introduce messages they have */ 07603 int res; 07604 07605 res = ast_play_and_wait(chan, "vm-youhave"); 07606 if (res) 07607 return res; 07608 07609 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07610 res = ast_play_and_wait(chan, "vm-no"); 07611 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07612 return res; 07613 } 07614 07615 if (vms->newmessages) { 07616 if ((vms->newmessages == 1)) { 07617 res = ast_play_and_wait(chan, "digits/ett"); 07618 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 07619 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07620 } else { 07621 res = say_and_wait(chan, vms->newmessages, chan->language); 07622 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 07623 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07624 } 07625 if (!res && vms->oldmessages) 07626 res = ast_play_and_wait(chan, "vm-and"); 07627 } 07628 if (!res && vms->oldmessages) { 07629 if (vms->oldmessages == 1) { 07630 res = ast_play_and_wait(chan, "digits/ett"); 07631 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 07632 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07633 } else { 07634 res = say_and_wait(chan, vms->oldmessages, chan->language); 07635 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 07636 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07637 } 07638 } 07639 07640 return res; 07641 }
| static int vm_intro_zh | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 8053 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08054 { 08055 int res; 08056 /* Introduce messages they have */ 08057 res = ast_play_and_wait(chan, "vm-you"); 08058 08059 if (!res && vms->newmessages) { 08060 res = ast_play_and_wait(chan, "vm-have"); 08061 if (!res) 08062 res = say_and_wait(chan, vms->newmessages, chan->language); 08063 if (!res) 08064 res = ast_play_and_wait(chan, "vm-tong"); 08065 if (!res) 08066 res = ast_play_and_wait(chan, "vm-INBOX"); 08067 if (vms->oldmessages && !res) 08068 res = ast_play_and_wait(chan, "vm-and"); 08069 else if (!res) 08070 res = ast_play_and_wait(chan, "vm-messages"); 08071 } 08072 if (!res && vms->oldmessages) { 08073 res = ast_play_and_wait(chan, "vm-have"); 08074 if (!res) 08075 res = say_and_wait(chan, vms->oldmessages, chan->language); 08076 if (!res) 08077 res = ast_play_and_wait(chan, "vm-tong"); 08078 if (!res) 08079 res = ast_play_and_wait(chan, "vm-Old"); 08080 if (!res) 08081 res = ast_play_and_wait(chan, "vm-messages"); 08082 } 08083 if (!res && !vms->oldmessages && !vms->newmessages) { 08084 res = ast_play_and_wait(chan, "vm-haveno"); 08085 if (!res) 08086 res = ast_play_and_wait(chan, "vm-messages"); 08087 } 08088 return res; 08089 }
| 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 2783 of file app_voicemail.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
Referenced by close_mailbox(), copy_message(), count_messages(), leave_voicemail(), open_mailbox(), and save_to_folder().
02784 { 02785 switch (ast_lock_path(path)) { 02786 case AST_LOCK_TIMEOUT: 02787 return -1; 02788 default: 02789 return 0; 02790 } 02791 }
| static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1304 of file app_voicemail.c.
References VOICEMAIL_FILE_MODE.
Referenced by sendmail(), and sendpage().
01305 { 01306 FILE *p = NULL; 01307 int pfd = mkstemp(template); 01308 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01309 if (pfd > -1) { 01310 p = fdopen(pfd, "w+"); 01311 if (!p) { 01312 close(pfd); 01313 pfd = -1; 01314 } 01315 } 01316 return p; 01317 }
| 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 8261 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, 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().
08262 { 08263 int cmd = 0; 08264 int duration = 0; 08265 int tries = 0; 08266 char newpassword[80] = ""; 08267 char newpassword2[80] = ""; 08268 char prefile[PATH_MAX] = ""; 08269 unsigned char buf[256]; 08270 int bytes=0; 08271 08272 if (ast_adsi_available(chan)) { 08273 bytes += adsi_logo(buf + bytes); 08274 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 08275 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 08276 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 08277 bytes += ast_adsi_voice_mode(buf + bytes, 0); 08278 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 08279 } 08280 08281 /* First, have the user change their password 08282 so they won't get here again */ 08283 for (;;) { 08284 newpassword[1] = '\0'; 08285 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 08286 if (cmd == '#') 08287 newpassword[0] = '\0'; 08288 if (cmd < 0 || cmd == 't' || cmd == '#') 08289 return cmd; 08290 cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#"); 08291 if (cmd < 0 || cmd == 't' || cmd == '#') 08292 return cmd; 08293 cmd = check_password(vmu, newpassword); /* perform password validation */ 08294 if (cmd != 0) { 08295 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 08296 cmd = ast_play_and_wait(chan, vm_invalid_password); 08297 } else { 08298 newpassword2[1] = '\0'; 08299 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 08300 if (cmd == '#') 08301 newpassword2[0] = '\0'; 08302 if (cmd < 0 || cmd == 't' || cmd == '#') 08303 return cmd; 08304 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 08305 if (cmd < 0 || cmd == 't' || cmd == '#') 08306 return cmd; 08307 if (!strcmp(newpassword, newpassword2)) 08308 break; 08309 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 08310 cmd = ast_play_and_wait(chan, vm_mismatch); 08311 } 08312 if (++tries == 3) 08313 return -1; 08314 if (cmd != 0) { 08315 cmd = ast_play_and_wait(chan, vm_pls_try_again); 08316 } 08317 } 08318 if (pwdchange & PWDCHANGE_INTERNAL) 08319 vm_change_password(vmu, newpassword); 08320 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 08321 vm_change_password_shell(vmu, newpassword); 08322 08323 ast_debug(1,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword)); 08324 cmd = ast_play_and_wait(chan, vm_passchanged); 08325 08326 /* If forcename is set, have the user record their name */ 08327 if (ast_test_flag(vmu, VM_FORCENAME)) { 08328 snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 08329 if (ast_fileexists(prefile, NULL, NULL) < 1) { 08330 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08331 if (cmd < 0 || cmd == 't' || cmd == '#') 08332 return cmd; 08333 } 08334 } 08335 08336 /* If forcegreetings is set, have the user record their greetings */ 08337 if (ast_test_flag(vmu, VM_FORCEGREET)) { 08338 snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 08339 if (ast_fileexists(prefile, NULL, NULL) < 1) { 08340 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08341 if (cmd < 0 || cmd == 't' || cmd == '#') 08342 return cmd; 08343 } 08344 08345 snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 08346 if (ast_fileexists(prefile, NULL, NULL) < 1) { 08347 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08348 if (cmd < 0 || cmd == 't' || cmd == '#') 08349 return cmd; 08350 } 08351 } 08352 08353 return cmd; 08354 }
| 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 8356 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_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().
08357 { 08358 int cmd = 0; 08359 int retries = 0; 08360 int duration = 0; 08361 char newpassword[80] = ""; 08362 char newpassword2[80] = ""; 08363 char prefile[PATH_MAX] = ""; 08364 unsigned char buf[256]; 08365 int bytes=0; 08366 08367 if (ast_adsi_available(chan)) { 08368 bytes += adsi_logo(buf + bytes); 08369 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 08370 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 08371 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 08372 bytes += ast_adsi_voice_mode(buf + bytes, 0); 08373 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 08374 } 08375 while ((cmd >= 0) && (cmd != 't')) { 08376 if (cmd) 08377 retries = 0; 08378 switch (cmd) { 08379 case '1': /* Record your unavailable message */ 08380 snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 08381 cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08382 break; 08383 case '2': /* Record your busy message */ 08384 snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 08385 cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08386 break; 08387 case '3': /* Record greeting */ 08388 snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 08389 cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08390 break; 08391 case '4': /* manage the temporary greeting */ 08392 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 08393 break; 08394 case '5': /* change password */ 08395 if (vmu->password[0] == '-') { 08396 cmd = ast_play_and_wait(chan, "vm-no"); 08397 break; 08398 } 08399 newpassword[1] = '\0'; 08400 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 08401 if (cmd == '#') 08402 newpassword[0] = '\0'; 08403 else { 08404 if (cmd < 0) 08405 break; 08406 if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) { 08407 break; 08408 } 08409 } 08410 cmd = check_password(vmu, newpassword); /* perform password validation */ 08411 if (cmd != 0) { 08412 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 08413 cmd = ast_play_and_wait(chan, vm_invalid_password); 08414 if (!cmd) { 08415 cmd = ast_play_and_wait(chan, vm_pls_try_again); 08416 } 08417 break; 08418 } 08419 newpassword2[1] = '\0'; 08420 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 08421 if (cmd == '#') 08422 newpassword2[0] = '\0'; 08423 else { 08424 if (cmd < 0) 08425 break; 08426 08427 if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#")) < 0) { 08428 break; 08429 } 08430 } 08431 if (strcmp(newpassword, newpassword2)) { 08432 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 08433 cmd = ast_play_and_wait(chan, vm_mismatch); 08434 if (!cmd) { 08435 cmd = ast_play_and_wait(chan, vm_pls_try_again); 08436 } 08437 break; 08438 } 08439 if (pwdchange & PWDCHANGE_INTERNAL) 08440 vm_change_password(vmu, newpassword); 08441 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 08442 vm_change_password_shell(vmu, newpassword); 08443 08444 ast_debug(1,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword)); 08445 cmd = ast_play_and_wait(chan, vm_passchanged); 08446 break; 08447 case '*': 08448 cmd = 't'; 08449 break; 08450 default: 08451 cmd = 0; 08452 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08453 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08454 if (ast_fileexists(prefile, NULL, NULL)) { 08455 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 08456 } 08457 DISPOSE(prefile, -1); 08458 if (!cmd) { 08459 cmd = ast_play_and_wait(chan, "vm-options"); 08460 } 08461 if (!cmd) { 08462 cmd = ast_waitfordigit(chan,6000); 08463 } 08464 if (!cmd) { 08465 retries++; 08466 } 08467 if (retries > 3) { 08468 cmd = 't'; 08469 } 08470 } 08471 } 08472 if (cmd == 't') 08473 cmd = 0; 08474 return cmd; 08475 }
| static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
| char * | mbox | |||
| ) | [static] |
Definition at line 7201 of file app_voicemail.c.
References ast_play_and_wait(), vm_play_folder_name_gr(), vm_play_folder_name_pl(), and vm_play_folder_name_ua().
Referenced by get_folder(), vm_execmain(), vm_instructions_en(), and vm_instructions_zh().
07202 { 07203 int cmd; 07204 07205 if ( !strncasecmp(chan->language, "it", 2) || 07206 !strncasecmp(chan->language, "es", 2) || 07207 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 07208 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07209 return cmd ? cmd : ast_play_and_wait(chan, box); 07210 } else if (!strncasecmp(chan->language, "gr", 2)) { 07211 return vm_play_folder_name_gr(chan, box); 07212 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 07213 return ast_play_and_wait(chan, box); 07214 } else if (!strncasecmp(chan->language, "pl", 2)) { 07215 return vm_play_folder_name_pl(chan, box); 07216 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 07217 return vm_play_folder_name_ua(chan, box); 07218 } else { /* Default English */ 07219 cmd = ast_play_and_wait(chan, box); 07220 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07221 } 07222 }
| static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 7154 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
07155 { 07156 int cmd; 07157 char *buf; 07158 07159 buf = alloca(strlen(box)+2); 07160 strcpy(buf, box); 07161 strcat(buf,"s"); 07162 07163 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 07164 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 07165 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07166 } else { 07167 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07168 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 07169 } 07170 }
| static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 7172 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
07173 { 07174 int cmd; 07175 07176 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 07177 if (!strcasecmp(box, "vm-INBOX")) 07178 cmd = ast_play_and_wait(chan, "vm-new-e"); 07179 else 07180 cmd = ast_play_and_wait(chan, "vm-old-e"); 07181 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07182 } else { 07183 cmd = ast_play_and_wait(chan, "vm-messages"); 07184 return cmd ? cmd : ast_play_and_wait(chan, box); 07185 } 07186 }
| static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
| char * | box | |||
| ) | [static] |
Definition at line 7188 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
07189 { 07190 int cmd; 07191 07192 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 07193 cmd = ast_play_and_wait(chan, "vm-messages"); 07194 return cmd ? cmd : ast_play_and_wait(chan, box); 07195 } else { 07196 cmd = ast_play_and_wait(chan, box); 07197 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07198 } 07199 }
| 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 8493 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_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::mailbox, play_record_review(), RETRIEVE, and vm_state::username.
Referenced by vm_options().
08494 { 08495 int cmd = 0; 08496 int retries = 0; 08497 int duration = 0; 08498 char prefile[PATH_MAX] = ""; 08499 unsigned char buf[256]; 08500 int bytes = 0; 08501 08502 if (ast_adsi_available(chan)) { 08503 bytes += adsi_logo(buf + bytes); 08504 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 08505 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 08506 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 08507 bytes += ast_adsi_voice_mode(buf + bytes, 0); 08508 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 08509 } 08510 08511 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08512 while ((cmd >= 0) && (cmd != 't')) { 08513 if (cmd) 08514 retries = 0; 08515 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08516 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 08517 play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08518 cmd = 't'; 08519 } else { 08520 switch (cmd) { 08521 case '1': 08522 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08523 break; 08524 case '2': 08525 DELETE(prefile, -1, prefile, vmu); 08526 ast_play_and_wait(chan, "vm-tempremoved"); 08527 cmd = 't'; 08528 break; 08529 case '*': 08530 cmd = 't'; 08531 break; 08532 default: 08533 cmd = ast_play_and_wait(chan, 08534 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 08535 "vm-tempgreeting2" : "vm-tempgreeting"); 08536 if (!cmd) 08537 cmd = ast_waitfordigit(chan,6000); 08538 if (!cmd) 08539 retries++; 08540 if (retries > 3) 08541 cmd = 't'; 08542 } 08543 } 08544 DISPOSE(prefile, -1); 08545 } 08546 if (cmd == 't') 08547 cmd = 0; 08548 return cmd; 08549 }
| static int vmauthenticate | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 9779 of file app_voicemail.c.
References ast_copy_string(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_vm_user::context, pbx_builtin_setvar_helper(), s, strsep(), and vm_authenticate().
Referenced by load_module().
09780 { 09781 char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = ""; 09782 struct ast_vm_user vmus; 09783 char *options = NULL; 09784 int silent = 0, skipuser = 0; 09785 int res = -1; 09786 09787 if (s) { 09788 s = ast_strdupa(s); 09789 user = strsep(&s, ","); 09790 options = strsep(&s, ","); 09791 if (user) { 09792 s = user; 09793 user = strsep(&s, "@"); 09794 context = strsep(&s, ""); 09795 if (!ast_strlen_zero(user)) 09796 skipuser++; 09797 ast_copy_string(mailbox, user, sizeof(mailbox)); 09798 } 09799 } 09800 09801 if (options) { 09802 silent = (strchr(options, 's')) != NULL; 09803 } 09804 09805 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 09806 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 09807 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 09808 ast_play_and_wait(chan, "auth-thankyou"); 09809 res = 0; 09810 } 09811 09812 return res; 09813 }
| 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. Return tm so it can be used as a function argument.
Definition at line 3875 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().
03876 { 03877 const struct vm_zone *z = NULL; 03878 struct timeval t = ast_tvnow(); 03879 03880 /* Does this user have a timezone specified? */ 03881 if (!ast_strlen_zero(vmu->zonetag)) { 03882 /* Find the zone in the list */ 03883 AST_LIST_LOCK(&zones); 03884 AST_LIST_TRAVERSE(&zones, z, list) { 03885 if (!strcmp(z->name, vmu->zonetag)) 03886 break; 03887 } 03888 AST_LIST_UNLOCK(&zones); 03889 } 03890 ast_localtime(&t, tm, z ? z->timezone : NULL); 03891 return tm; 03892 }
| static int wait_file | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | file | |||
| ) | [static] |
Definition at line 6613 of file app_voicemail.c.
References ast_control_streamfile(), 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(), and play_message().
06614 { 06615 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); 06616 }
| static int wait_file2 | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | file | |||
| ) | [static] |
Definition at line 6605 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().
06606 { 06607 int res; 06608 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 06609 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 06610 return res; 06611 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "DAHDI Telephony w/PRI & SS7" , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 11595 of file app_voicemail.c.
char* addesc = "Comedian Mail" [static] |
Definition at line 507 of file app_voicemail.c.
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 700 of file app_voicemail.c.
Referenced by adsi_begin(), adsi_load_vmail(), and load_config().
unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC" [static] |
Definition at line 701 of file app_voicemail.c.
Referenced by adsi_load_vmail(), and load_config().
int adsiver = 1 [static] |
Definition at line 702 of file app_voicemail.c.
Referenced by adsi_begin(), adsi_load_vmail(), and load_config().
char* app = "VoiceMail" [static] |
Definition at line 592 of file app_voicemail.c.
char* app2 = "VoiceMailMain" [static] |
Definition at line 595 of file app_voicemail.c.
char* app3 = "MailboxExists" [static] |
Definition at line 597 of file app_voicemail.c.
char* app4 = "VMAuthenticate" [static] |
Definition at line 598 of file app_voicemail.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 11595 of file app_voicemail.c.
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 686 of file app_voicemail.c.
Referenced by load_config(), and populate_defaults().
char charset[32] = "ISO-8859-1" [static] |
Definition at line 698 of file app_voicemail.c.
Referenced by encode_mime_str(), load_config(), make_email_file(), and tds_load_module().
char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static] |
Definition at line 689 of file app_voicemail.c.
Referenced by load_config(), and play_message_callerid().
struct ast_cli_entry cli_voicemail[] [static] |
{
AST_CLI_DEFINE(handle_voicemail_show_users, "List defined voicemail boxes"),
AST_CLI_DEFINE(handle_voicemail_show_zones, "List zone message formats"),
AST_CLI_DEFINE(handle_voicemail_reload, "Reload voicemail configuration"),
}
Definition at line 10011 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* descrip_vm [static] |
Definition at line 511 of file app_voicemail.c.
char* descrip_vm_box_exists [static] |
Definition at line 569 of file app_voicemail.c.
char* descrip_vmain [static] |
Definition at line 540 of file app_voicemail.c.
char* descrip_vmauthenticate [static] |
Definition at line 581 of file app_voicemail.c.
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 685 of file app_voicemail.c.
Referenced by dial_exec_full(), directory_exec(), load_config(), populate_defaults(), ring_entry(), and wait_for_answer().
char* emailbody = NULL [static] |
Definition at line 692 of file app_voicemail.c.
Referenced by load_config(), make_email_file(), and message_template_parse_emailbody().
char emaildateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 703 of file app_voicemail.c.
Referenced by load_config(), make_email_file(), and prep_email_sub_vars().
char* emailsubject = NULL [static] |
Definition at line 693 of file app_voicemail.c.
Referenced by load_config(), and make_email_file().
char exitcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 687 of file app_voicemail.c.
Referenced by common_exec(), conf_run(), load_config(), and populate_defaults().
char ext_pass_check_cmd[128] [static] |
Definition at line 487 of file app_voicemail.c.
char ext_pass_cmd[128] [static] |
Definition at line 486 of file app_voicemail.c.
char externnotify[160] [static] |
Definition at line 609 of file app_voicemail.c.
char fromstring[100] [static] |
Definition at line 696 of file app_voicemail.c.
Referenced by load_config(), make_email_file(), and sendpage().
struct ast_flags globalflags = {0} [static] |
Definition at line 681 of file app_voicemail.c.
Referenced by find_or_create(), find_user(), find_user_realtime(), forward_message(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), sendmail(), and vm_execmain().
char listen_control_forward_key[12] [static] |
Definition at line 666 of file app_voicemail.c.
Referenced by load_config(), and wait_file().
char listen_control_pause_key[12] [static] |
Definition at line 668 of file app_voicemail.c.
Referenced by load_config(), and wait_file().
char listen_control_restart_key[12] [static] |
Definition at line 669 of file app_voicemail.c.
Referenced by load_config(), and wait_file().
char listen_control_reverse_key[12] [static] |
Definition at line 667 of file app_voicemail.c.
Referenced by load_config(), and wait_file().
char listen_control_stop_key[12] [static] |
Definition at line 670 of file app_voicemail.c.
Referenced by load_config(), and wait_file().
struct ast_custom_function mailbox_exists_acf [static] |
Definition at line 9769 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char mailcmd[160] [static] |
Definition at line 608 of file app_voicemail.c.
int maxdeletedmsg [static] |
Definition at line 605 of file app_voicemail.c.
int maxgreet [static] |
Definition at line 615 of file app_voicemail.c.
int maxlogins [static] |
Definition at line 617 of file app_voicemail.c.
int maxmsg [static] |
Definition at line 604 of file app_voicemail.c.
int maxsilence [static] |
Definition at line 603 of file app_voicemail.c.
Referenced by ast_record_review().
int minpassword [static] |
Definition at line 618 of file app_voicemail.c.
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 635 of file app_voicemail.c.
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 661 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 637 of file app_voicemail.c.
int my_umask [static] |
Definition at line 489 of file app_voicemail.c.
char* pagerbody = NULL [static] |
Definition at line 694 of file app_voicemail.c.
Referenced by load_config(), and sendpage().
char pagerfromstring[100] [static] |
Definition at line 697 of file app_voicemail.c.
Referenced by load_config(), and sendpage().
char* pagersubject = NULL [static] |
Definition at line 695 of file app_voicemail.c.
Referenced by load_config(), and sendpage().
ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 630 of file app_voicemail.c.
unsigned int poll_freq [static] |
Polling frequency
Definition at line 625 of file app_voicemail.c.
ast_mutex_t poll_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 629 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 622 of file app_voicemail.c.
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 631 of file app_voicemail.c.
unsigned char poll_thread_run [static] |
Definition at line 632 of file app_voicemail.c.
int pwdchange = PWDCHANGE_INTERNAL [static] |
Definition at line 493 of file app_voicemail.c.
int saydurationminfo [static] |
Definition at line 683 of file app_voicemail.c.
Referenced by load_config(), and populate_defaults().
char serveremail[80] [static] |
Definition at line 607 of file app_voicemail.c.
int silencethreshold = 128 [static] |
Definition at line 606 of file app_voicemail.c.
int skipms [static] |
Definition at line 616 of file app_voicemail.c.
Referenced by controlplayback_exec(), and handle_controlstreamfile().
struct ast_smdi_interface* smdi_iface = NULL [static] |
Definition at line 610 of file app_voicemail.c.
char* synopsis_vm = "Leave a Voicemail message" [static] |
Definition at line 509 of file app_voicemail.c.
char* synopsis_vm_box_exists [static] |
"Check to see if Voicemail mailbox exists"
Definition at line 566 of file app_voicemail.c.
char* synopsis_vmain = "Check Voicemail messages" [static] |
Definition at line 538 of file app_voicemail.c.
char* synopsis_vmauthenticate = "Authenticate with Voicemail passwords" [static] |
Definition at line 579 of file app_voicemail.c.
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 505 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] |
Definition at line 282 of file app_voicemail.c.
Referenced by vm_exec(), and vm_execmain().
| enum { ... } vm_box |
char vm_invalid_password[80] = "vm-invalid-password" [static] |
Definition at line 678 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char vm_mismatch[80] = "vm-mismatch" [static] |
Definition at line 677 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char vm_newpassword[80] = "vm-newpassword" [static] |
Definition at line 674 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
| enum { ... } vm_option_args |
| enum { ... } vm_option_flags |
char vm_passchanged[80] = "vm-passchanged" [static] |
Definition at line 675 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char vm_password[80] = "vm-password" [static] |
Definition at line 673 of file app_voicemail.c.
Referenced by load_config(), and vm_authenticate().
char vm_pls_try_again[80] = "vm-pls-try-again" [static] |
Definition at line 679 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 676 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char VM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 484 of file app_voicemail.c.
char vmfmts[80] [static] |
Definition at line 611 of file app_voicemail.c.
int vmmaxsecs [static] |
Definition at line 614 of file app_voicemail.c.
int vmminsecs [static] |
Definition at line 613 of file app_voicemail.c.
double volgain [static] |
Definition at line 612 of file app_voicemail.c.
char zonetag[80] [static] |
Definition at line 602 of file app_voicemail.c.
Referenced by build_peer().
1.6.1