#include "asterisk.h"
#include "asterisk/paths.h"
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include "asterisk/logger.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/module.h"
#include "asterisk/adsi.h"
#include "asterisk/app.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/stringfields.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj2.h"
#include "asterisk/event.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
Go to the source code of this file.
Data Structures | |
struct | ast_vm_user |
struct | baseio |
struct | inprocess |
struct | leave_vm_options |
Options for leaving voicemail with the voicemail() application. More... | |
struct | mwi_sub |
An MWI subscription. More... | |
struct | mwi_sub_task |
struct | mwi_subs |
struct | users |
list of users found in the config file More... | |
struct | vm_state |
struct | vm_zone |
struct | zones |
Defines | |
#define | ASTERISK_USERNAME "asterisk" |
#define | BASELINELEN 72 |
#define | BASEMAXINLINE 256 |
#define | CHUNKSIZE 65536 |
#define | COMMAND_TIMEOUT 5000 |
#define | COPY(a, b, c, d, e, f, g, h) (copy_plain_file(g,h)); |
#define | DATA_EXPORT_VM_USERS(USER) |
#define | DATA_EXPORT_VM_ZONES(ZONE) |
#define | DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
#define | DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
#define | DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
#define | DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
#define | DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
#define | DEFAULT_POLL_FREQ 30 |
#define | DELETE(a, b, c, d) (vm_delete(c)) |
#define | DISPOSE(a, b) |
#define | ENDL "\n" |
#define | ERROR_LOCK_PATH -100 |
#define | EXISTS(a, b, c, d) (ast_fileexists(c,NULL,d) > 0) |
#define | HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
#define | HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
#define | INTRO "vm-intro" |
#define | MAX_DATETIME_FORMAT 512 |
#define | MAX_NUM_CID_CONTEXTS 10 |
#define | MAXMSG 100 |
#define | MAXMSGLIMIT 9999 |
#define | MINPASSWORD 0 |
#define | OPERATOR_EXIT 300 |
#define | PWDCHANGE_EXTERNAL (1 << 2) |
#define | PWDCHANGE_INTERNAL (1 << 1) |
#define | RENAME(a, b, c, d, e, f, g, h) (rename_file(g,h)); |
#define | RETRIEVE(a, b, c, d) |
#define | SENDMAIL "/usr/sbin/sendmail -t" |
#define | SMDI_MWI_WAIT_TIMEOUT 1000 |
#define | STORE(a, b, c, d, e, f, g, h, i, j) |
#define | tdesc "Comedian Mail (Voicemail System)" |
#define | VALID_DTMF "1234567890*#" |
#define | VM_ALLOCED (1 << 13) |
#define | VM_ATTACH (1 << 11) |
#define | VM_DELETE (1 << 12) |
#define | VM_DIRECFORWARD (1 << 10) |
#define | VM_ENVELOPE (1 << 4) |
#define | VM_FORCEGREET (1 << 8) |
#define | VM_FORCENAME (1 << 7) |
#define | VM_FWDURGAUTO (1 << 18) |
#define | VM_MESSAGEWRAP (1 << 17) |
#define | VM_MOVEHEARD (1 << 16) |
#define | VM_OPERATOR (1 << 1) |
#define | VM_PBXSKIP (1 << 9) |
#define | VM_REVIEW (1 << 0) |
#define | VM_SAYCID (1 << 2) |
#define | VM_SAYDURATION (1 << 5) |
#define | VM_SEARCH (1 << 14) |
#define | VM_SKIPAFTERCMD (1 << 6) |
#define | VM_SVMAIL (1 << 3) |
#define | VM_TEMPGREETWARN (1 << 15) |
#define | VMSTATE_MAX_MSG_ARRAY 256 |
#define | VOICEMAIL_CONFIG "voicemail.conf" |
#define | VOICEMAIL_DIR_MODE 0777 |
#define | VOICEMAIL_FILE_MODE 0666 |
Enumerations | |
enum | vm_box { NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER } |
enum | vm_option_args { OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3 } |
enum | vm_option_flags { OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9) } |
enum | vm_passwordlocation { OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2 } |
Functions | |
static 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 | actual_load_config (int reload, struct ast_config *cfg, struct ast_config *ucfg) |
static int | add_email_attachment (FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum) |
static void | adsi_begin (struct ast_channel *chan, int *useadsi) |
static void | adsi_delete (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_folders (struct ast_channel *chan, int start, char *label) |
static void | adsi_goodbye (struct ast_channel *chan) |
static int | adsi_load_vmail (struct ast_channel *chan, int *useadsi) |
static void | adsi_login (struct ast_channel *chan) |
static int | adsi_logo (unsigned char *buf) |
static void | adsi_message (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_password (struct ast_channel *chan) |
static void | adsi_status (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_status2 (struct ast_channel *chan, struct vm_state *vms) |
static int | advanced_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain) |
The advanced options within a message. | |
static int | append_mailbox (const char *context, const char *box, const char *data) |
static void | apply_option (struct ast_vm_user *vmu, const char *var, const char *value) |
Sets a a specific property value. | |
static void | apply_options (struct ast_vm_user *vmu, const char *options) |
Destructively Parse options and apply. | |
static void | apply_options_full (struct ast_vm_user *retval, struct ast_variable *var) |
Loads the options specific to a voicemail user. | |
AST_DATA_STRUCTURE (vm_zone, DATA_EXPORT_VM_ZONES) | |
AST_DATA_STRUCTURE (ast_vm_user, DATA_EXPORT_VM_USERS) | |
static const char * | ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *start, size_t preamble, size_t postamble) |
Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters. | |
static const char * | ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from) |
Wraps a character sequence in double quotes, escaping occurences of quotes within the string. | |
AST_TEST_DEFINE (test_voicemail_vmuser) | |
static int | base_encode (char *filename, FILE *so) |
Performs a base 64 encode algorithm on the contents of a File. | |
static int | change_password_realtime (struct ast_vm_user *vmu, const char *password) |
Performs a change of the voicemail passowrd in the realtime engine. | |
static int | check_mime (const char *str) |
Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean. | |
static int | check_password (struct ast_vm_user *vmu, char *password) |
Check that password meets minimum required length. | |
static int | close_mailbox (struct vm_state *vms, struct ast_vm_user *vmu) |
static char * | complete_voicemail_show_users (const char *line, const char *word, int pos, int state) |
static int | copy (char *infile, char *outfile) |
Utility function to copy a file. | |
static int | copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir, const char *flag) |
Copies a message from one mailbox to another. | |
static void | copy_plain_file (char *frompath, char *topath) |
Copies a voicemail information (envelope) file. | |
static int | count_messages (struct ast_vm_user *vmu, char *dir) |
Find all .txt files - even if they are not in sequence from 0000. | |
static int | create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder) |
basically mkdir -p $dest/$context/$ext/$folder | |
static int | dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context) |
static struct ast_vm_user * | find_or_create (const char *context, const char *box) |
static struct ast_vm_user * | find_user (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the users file or the realtime engine. | |
static struct ast_vm_user * | find_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the realtime engine. | |
static int | forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int is_new_message, signed char record_gain, int urgent) |
Sends a voicemail message to a mailbox recipient. | |
static void | free_user (struct ast_vm_user *vmu) |
static void | free_vm_users (void) |
Free the users structure. | |
static void | free_vm_zones (void) |
Free the zones structure. | |
static void | free_zone (struct vm_zone *z) |
static int | get_date (char *s, int len) |
Gets the current date and time, as formatted string. | |
static int | get_folder (struct ast_channel *chan, int start) |
get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized | |
static int | get_folder2 (struct ast_channel *chan, char *fn, int start) |
plays a prompt and waits for a keypress. | |
static int | get_folder_by_name (const char *name) |
static int | handle_subscribe (void *datap) |
static int | handle_unsubscribe (void *datap) |
static char * | handle_voicemail_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Reload voicemail configuration from the CLI. | |
static char * | handle_voicemail_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail users in the CLI. | |
static char * | handle_voicemail_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail zones in the CLI. | |
static int | has_voicemail (const char *mailbox, const char *folder) |
Determines if the given folder has messages. | |
static int | inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs) |
static int | inboxcount2 (const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs) |
static int | inbuf (struct baseio *bio, FILE *fi) |
utility used by inchar(), for base_encode() | |
static int | inchar (struct baseio *bio, FILE *fi) |
utility used by base_encode() | |
static int | inprocess_cmp_fn (void *obj, void *arg, int flags) |
static int | inprocess_count (const char *context, const char *mailbox, int delta) |
static int | inprocess_hash_fn (const void *obj, const int flags) |
static int | invent_message (struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes) |
static int | is_valid_dtmf (const char *key) |
Determines if a DTMF key entered is valid. | |
static int | last_message_index (struct ast_vm_user *vmu, char *dir) |
Determines the highest message number in use for a given user and mailbox folder. | |
static int | leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options) |
Prompts the user and records a voicemail to a mailbox. | |
static int | load_config (int reload) |
static int | load_module (void) |
static int | make_dir (char *dest, int len, const char *context, const char *ext, const char *folder) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static void | make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag) |
Creates the email file to be sent to indicate a new voicemail exists for a user. | |
static int | make_file (char *dest, const int len, const char *dir, const int num) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static int | manager_list_voicemail_users (struct mansession *s, const struct message *m) |
Manager list voicemail users command. | |
static void * | mb_poll_thread (void *data) |
static const char * | mbox (struct ast_vm_user *vmu, int id) |
static int | messagecount (const char *context, const char *mailbox, const char *folder) |
static void | mwi_sub_destroy (struct mwi_sub *mwi_sub) |
static void | mwi_sub_event_cb (const struct ast_event *event, void *userdata) |
static void | mwi_unsub_event_cb (const struct ast_event *event, void *userdata) |
static int | notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag) |
Sends email notification that a user has a new voicemail waiting for them. | |
static int | ochar (struct baseio *bio, int c, FILE *so) |
utility used by base_encode() | |
static int | open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box) |
static int | play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback) |
static int | play_message_category (struct ast_channel *chan, const char *category) |
static int | play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename) |
static int | play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration) |
static int | play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag) |
static void | poll_subscribed_mailbox (struct mwi_sub *mwi_sub) |
static void | poll_subscribed_mailboxes (void) |
static void | populate_defaults (struct ast_vm_user *vmu) |
Sets default voicemail system options to a voicemail user. | |
static void | prep_email_sub_vars (struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, const char *category, const char *flag) |
static void | queue_mwi_event (const char *box, int urgent, int new, int old) |
static void | read_password_from_file (const char *secretfn, char *password, int passwordlen) |
static int | reload (void) |
static void | rename_file (char *sfn, char *dfn) |
Renames a message in a mailbox folder. | |
static int | resequence_mailbox (struct ast_vm_user *vmu, char *dir, int stopcount) |
static int | reset_user_pw (const char *context, const char *mailbox, const char *newpass) |
Resets a user password to a specified password. | |
static void | run_externnotify (char *context, char *extension, const char *flag) |
static int | save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box) |
static int | say_and_wait (struct ast_channel *chan, int num, const char *language) |
static int | sayname (struct ast_channel *chan, const char *mailbox, const char *context) |
static int | sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag) |
static int | sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag) |
static char * | show_users_realtime (int fd, const char *context) |
static void | start_poll_thread (void) |
static void | stop_poll_thread (void) |
static char * | strip_control_and_high (const char *input, char *buf, size_t buflen) |
Strips control and non 7-bit clean characters from input string. | |
static const char * | substitute_escapes (const char *value) |
static int | unload_module (void) |
static int | vm_allocate_dh (struct vm_state *vms, struct ast_vm_user *vmu, int count_msg) |
static int | vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int max_logins, int silent) |
static int | vm_box_exists (struct ast_channel *chan, const char *data) |
static int | vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Top level method to invoke the language variant vm_browse_messages_XX function. | |
static int | vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Default English syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Spanish syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Greek syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
static int | vm_browse_messages_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Italian syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Portuguese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_vi (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Vietnamese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_zh (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Chinese (Taiwan)syntax for 'You have N messages' greeting. | |
static void | vm_change_password (struct ast_vm_user *vmu, const char *newpassword) |
The handler for the change password option. | |
static void | vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword) |
static char * | vm_check_password_shell (char *command, char *buf, size_t len) |
static int | vm_delete (char *file) |
Removes the voicemail sound and information file. | |
static int | vm_exec (struct ast_channel *chan, const char *data) |
static int | vm_execmain (struct ast_channel *chan, const char *data) |
static int | vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts, char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag) |
presents the option to prepend to an existing message when forwarding it. | |
static int | vm_instructions (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_en (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_zh (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | vm_intro_cs (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_de (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_en (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_es (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_fr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_gr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_he (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_it (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[]) |
static int | vm_intro_nl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_no (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_se (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_vi (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_zh (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_lock_path (const char *path) |
Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason. | |
static FILE * | vm_mkftemp (char *template) |
static int | vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_play_folder_name (struct ast_channel *chan, char *mbox) |
static int | vm_play_folder_name_gr (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_pl (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_ua (struct ast_channel *chan, char *box) |
static int | vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
The handler for 'record a temporary greeting'. | |
static int | vm_users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static int | vm_users_data_provider_get_helper (const struct ast_data_search *search, struct ast_data *data_root, struct ast_vm_user *user) |
static int | vmauthenticate (struct ast_channel *chan, const char *data) |
static int | vmsayname_exec (struct ast_channel *chan, const char *data) |
static struct ast_tm * | vmu_tm (const struct ast_vm_user *vmu, struct ast_tm *tm) |
fill in *tm for current time according to the proper timezone, if any. | |
static int | wait_file (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | write_password_to_file (const char *secretfn, const char *password) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } |
static char * | addesc = "Comedian Mail" |
static unsigned char | adsifdn [4] = "\x00\x00\x00\x0F" |
static unsigned char | adsisec [4] = "\x9B\xDB\xF7\xAC" |
static int | adsiver = 1 |
static char * | app = "VoiceMail" |
static char * | app2 = "VoiceMailMain" |
static char * | app3 = "MailboxExists" |
static char * | app4 = "VMAuthenticate" |
static struct ast_module_info * | ast_module_info = &__mod_info |
static char | callcontext [AST_MAX_CONTEXT] = "" |
static char | charset [32] = "ISO-8859-1" |
static char | cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64] |
static struct ast_cli_entry | cli_voicemail [] |
static char | dialcontext [AST_MAX_CONTEXT] = "" |
static char * | emailbody = NULL |
static char | emaildateformat [32] = "%A, %B %d, %Y at %r" |
static char * | emailsubject = NULL |
static char | exitcontext [AST_MAX_CONTEXT] = "" |
static char | ext_pass_check_cmd [128] |
static char | ext_pass_cmd [128] |
static char | externnotify [160] |
static char | fromstring [100] |
static struct ast_flags | globalflags = {0} |
ao2_container * | inprocess_container |
static char | listen_control_forward_key [12] |
static char | listen_control_pause_key [12] |
static char | listen_control_restart_key [12] |
static char | listen_control_reverse_key [12] |
static char | listen_control_stop_key [12] |
static char | locale [20] |
static struct ast_custom_function | mailbox_exists_acf |
static const char *const | mailbox_folders [] |
static char | mailcmd [160] |
static int | maxdeletedmsg |
static int | maxgreet |
static int | maxlogins |
static int | maxmsg |
static int | maxsilence |
static int | minpassword |
static struct ast_event_sub * | mwi_sub_sub |
static struct ast_taskprocessor * | mwi_subscription_tps |
static struct ast_event_sub * | mwi_unsub_sub |
static int | my_umask |
static char * | pagerbody = NULL |
static char | pagerdateformat [32] = "%A, %B %d, %Y at %r" |
static char | pagerfromstring [100] |
static char * | pagersubject = NULL |
static int | passwordlocation |
static ast_cond_t | poll_cond = PTHREAD_COND_INITIALIZER |
static unsigned int | poll_freq |
static ast_mutex_t | poll_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
static unsigned int | poll_mailboxes |
static pthread_t | poll_thread = AST_PTHREADT_NULL |
static unsigned char | poll_thread_run |
static int | pwdchange = PWDCHANGE_INTERNAL |
static int | saydurationminfo |
static char * | sayname_app = "VMSayName" |
static char | serveremail [80] |
static int | silencethreshold = 128 |
static int | skipms |
static struct ast_smdi_interface * | smdi_iface = NULL |
static char | userscontext [AST_MAX_EXTENSION] = "default" |
static struct ast_app_option | vm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'd' ] = { .flag = OPT_DTMFEXIT , .arg_index = OPT_ARG_DTMFEXIT + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 }, [ 'U' ] = { .flag = OPT_MESSAGE_Urgent }, [ 'P' ] = { .flag = OPT_MESSAGE_PRIORITY }} |
static struct ast_data_entry | vm_data_providers [] |
static char | vm_invalid_password [80] = "vm-invalid-password" |
static char | vm_mismatch [80] = "vm-mismatch" |
static char | vm_newpassword [80] = "vm-newpassword" |
static char | vm_passchanged [80] = "vm-passchanged" |
static char | vm_password [80] = "vm-password" |
static char | vm_pls_try_again [80] = "vm-pls-try-again" |
static char | vm_prepend_timeout [80] = "vm-then-pound" |
static char | vm_reenterpassword [80] = "vm-reenterpassword" |
static char | VM_SPOOL_DIR [PATH_MAX] |
static struct ast_data_handler | vm_users_data_provider |
static char | vmfmts [80] |
static int | vmmaxsecs |
static int | vmminsecs |
static double | volgain |
static char | zonetag [80] |
This module requires res_adsi to load. This needs to be optional during compilation.
This file is now almost impossible to work with, due to all #ifdefs. Feels like the database code before realtime. Someone - please come up with a plan to clean this up.
Definition in file app_voicemail.c.
#define ASTERISK_USERNAME "asterisk" |
Definition at line 430 of file app_voicemail.c.
#define BASELINELEN 72 |
#define BASEMAXINLINE 256 |
#define CHUNKSIZE 65536 |
Definition at line 427 of file app_voicemail.c.
#define COMMAND_TIMEOUT 5000 |
Definition at line 423 of file app_voicemail.c.
#define COPY | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (copy_plain_file(g,h)); |
#define DATA_EXPORT_VM_USERS | ( | USER | ) |
Definition at line 11296 of file app_voicemail.c.
#define DATA_EXPORT_VM_ZONES | ( | ZONE | ) |
Value:
ZONE(vm_zone, name, AST_DATA_STRING) \ ZONE(vm_zone, timezone, AST_DATA_STRING) \ ZONE(vm_zone, msg_format, AST_DATA_STRING)
Definition at line 11324 of file app_voicemail.c.
#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
#define DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
#define DEFAULT_POLL_FREQ 30 |
By default, poll every 30 seconds
Definition at line 811 of file app_voicemail.c.
Referenced by actual_load_config().
#define DELETE | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (vm_delete(c)) |
Definition at line 742 of file app_voicemail.c.
Referenced by close_mailbox(), notify_new_message(), play_record_review(), and vm_tempgreeting().
#define DISPOSE | ( | a, | |||
b | ) |
Definition at line 737 of file app_voicemail.c.
Referenced by advanced_options(), forward_message(), invent_message(), leave_voicemail(), notify_new_message(), play_message(), play_record_review(), sayname(), vm_intro(), vm_options(), and vm_tempgreeting().
#define ENDL "\n" |
Definition at line 458 of file app_voicemail.c.
Referenced by add_email_attachment(), base_encode(), make_email_file(), ochar(), and sendpage().
#define ERROR_LOCK_PATH -100 |
Definition at line 483 of file app_voicemail.c.
#define EXISTS | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 739 of file app_voicemail.c.
Referenced by close_mailbox(), copy_message(), resequence_mailbox(), and save_to_folder().
#define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
Referenced by handle_voicemail_show_users().
#define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
Referenced by handle_voicemail_show_zones().
#define INTRO "vm-intro" |
Definition at line 446 of file app_voicemail.c.
Referenced by play_record_review(), and vm_forwardoptions().
#define MAX_DATETIME_FORMAT 512 |
Definition at line 461 of file app_voicemail.c.
#define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 462 of file app_voicemail.c.
#define MAXMSG 100 |
Definition at line 448 of file app_voicemail.c.
Referenced by actual_load_config(), and apply_option().
#define MAXMSGLIMIT 9999 |
Definition at line 449 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), and last_message_index().
#define MINPASSWORD 0 |
Default minimum mailbox password length
Definition at line 451 of file app_voicemail.c.
Referenced by actual_load_config().
#define OPERATOR_EXIT 300 |
#define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 754 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
#define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 753 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
#define RENAME | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (rename_file(g,h)); |
Definition at line 740 of file app_voicemail.c.
Referenced by close_mailbox(), resequence_mailbox(), and save_to_folder().
#define RETRIEVE | ( | a, | |||
b, | |||||
c, | |||||
d | ) |
Definition at line 736 of file app_voicemail.c.
Referenced by advanced_options(), forward_message(), invent_message(), leave_voicemail(), notify_new_message(), play_message(), sayname(), vm_intro(), vm_options(), and vm_tempgreeting().
#define SENDMAIL "/usr/sbin/sendmail -t" |
Definition at line 444 of file app_voicemail.c.
#define SMDI_MWI_WAIT_TIMEOUT 1000 |
#define STORE | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h, | |||||
i, | |||||
j | ) |
Definition at line 738 of file app_voicemail.c.
Referenced by copy_message(), forward_message(), and play_record_review().
#define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 763 of file app_voicemail.c.
#define VALID_DTMF "1234567890*#" |
#define VM_ALLOCED (1 << 13) |
Structure was malloc'ed, instead of placed in a return (usually static) buffer
Definition at line 477 of file app_voicemail.c.
Referenced by AST_TEST_DEFINE(), find_user(), find_user_realtime(), free_user(), and free_vm_users().
#define VM_ATTACH (1 << 11) |
Attach message to voicemail notifications?
Definition at line 475 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), forward_message(), manager_list_voicemail_users(), notify_new_message(), and sendmail().
#define VM_DELETE (1 << 12) |
Delete message after sending notification
Definition at line 476 of file app_voicemail.c.
Referenced by apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and notify_new_message().
#define VM_DIRECFORWARD (1 << 10) |
Permit caller to use the Directory app for selecting to which mailbox to forward a VM
Definition at line 474 of file app_voicemail.c.
Referenced by actual_load_config(), and forward_message().
#define VM_ENVELOPE (1 << 4) |
Play the envelope information (who-from, time received, etc.)
Definition at line 468 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_message().
#define VM_FORCEGREET (1 << 8) |
Have new users record their greetings
Definition at line 472 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_newuser().
#define VM_FORCENAME (1 << 7) |
Have new users record their name
Definition at line 471 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_newuser().
#define VM_FWDURGAUTO (1 << 18) |
Autoset of Urgent flag on forwarded Urgent messages set globally
Definition at line 482 of file app_voicemail.c.
Referenced by actual_load_config(), and forward_message().
#define VM_MESSAGEWRAP (1 << 17) |
Wrap around from the last message to the first, and vice-versa
Definition at line 481 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_instructions_en().
#define VM_MOVEHEARD (1 << 16) |
Move a "heard" message to Old after listening to it
Definition at line 480 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and close_mailbox().
#define VM_OPERATOR (1 << 1) |
Allow 0 to be pressed to go to 'o' extension
Definition at line 465 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), leave_voicemail(), manager_list_voicemail_users(), and play_record_review().
#define VM_PBXSKIP (1 << 9) |
Skip the [PBX] preamble in the Subject line of emails
Definition at line 473 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
#define VM_REVIEW (1 << 0) |
After recording, permit the caller to review the recording before saving
Definition at line 464 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_record_review().
#define VM_SAYCID (1 << 2) |
Repeat the CallerID info during envelope playback
Definition at line 466 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_message().
#define VM_SAYDURATION (1 << 5) |
Play the length of the message during envelope playback
Definition at line 469 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and play_message().
#define VM_SEARCH (1 << 14) |
Search all contexts for a matching mailbox
Definition at line 478 of file app_voicemail.c.
Referenced by actual_load_config(), find_or_create(), find_user(), and find_user_realtime().
#define VM_SKIPAFTERCMD (1 << 6) |
After deletion, assume caller wants to go to the next message
Definition at line 470 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_execmain().
#define VM_SVMAIL (1 << 3) |
Allow the user to compose a new VM from within VoicemailMain
Definition at line 467 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_execmain().
#define VM_TEMPGREETWARN (1 << 15) |
Remind user tempgreeting is set
Definition at line 479 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_intro().
#define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 678 of file app_voicemail.c.
#define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 429 of file app_voicemail.c.
#define VOICEMAIL_DIR_MODE 0777 |
Definition at line 425 of file app_voicemail.c.
#define VOICEMAIL_FILE_MODE 0666 |
Definition at line 426 of file app_voicemail.c.
Referenced by add_email_attachment(), copy(), and vm_mkftemp().
enum vm_box |
Definition at line 487 of file app_voicemail.c.
00487 { 00488 NEW_FOLDER, 00489 OLD_FOLDER, 00490 WORK_FOLDER, 00491 FAMILY_FOLDER, 00492 FRIENDS_FOLDER, 00493 GREETINGS_FOLDER 00494 };
enum vm_option_args |
Definition at line 508 of file app_voicemail.c.
00508 { 00509 OPT_ARG_RECORDGAIN = 0, 00510 OPT_ARG_PLAYFOLDER = 1, 00511 OPT_ARG_DTMFEXIT = 2, 00512 /* This *must* be the last value in this enum! */ 00513 OPT_ARG_ARRAY_SIZE = 3, 00514 };
enum vm_option_flags |
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 496 of file app_voicemail.c.
00496 { 00497 OPT_SILENT = (1 << 0), 00498 OPT_BUSY_GREETING = (1 << 1), 00499 OPT_UNAVAIL_GREETING = (1 << 2), 00500 OPT_RECORDGAIN = (1 << 3), 00501 OPT_PREPEND_MAILBOX = (1 << 4), 00502 OPT_AUTOPLAY = (1 << 6), 00503 OPT_DTMFEXIT = (1 << 7), 00504 OPT_MESSAGE_Urgent = (1 << 8), 00505 OPT_MESSAGE_PRIORITY = (1 << 9) 00506 };
enum vm_passwordlocation |
Definition at line 516 of file app_voicemail.c.
00516 { 00517 OPT_PWLOC_VOICEMAILCONF = 0, 00518 OPT_PWLOC_SPOOLDIR = 1, 00519 OPT_PWLOC_USERSCONF = 2, 00520 };
static int __has_voicemail | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder, | |||
int | shortcircuit | |||
) | [static] |
Definition at line 5372 of file app_voicemail.c.
References ast_strlen_zero(), and VM_SPOOL_DIR.
Referenced by has_voicemail(), inboxcount2(), and messagecount().
05373 { 05374 DIR *dir; 05375 struct dirent *de; 05376 char fn[256]; 05377 int ret = 0; 05378 05379 /* If no mailbox, return immediately */ 05380 if (ast_strlen_zero(mailbox)) 05381 return 0; 05382 05383 if (ast_strlen_zero(folder)) 05384 folder = "INBOX"; 05385 if (ast_strlen_zero(context)) 05386 context = "default"; 05387 05388 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05389 05390 if (!(dir = opendir(fn))) 05391 return 0; 05392 05393 while ((de = readdir(dir))) { 05394 if (!strncasecmp(de->d_name, "msg", 3)) { 05395 if (shortcircuit) { 05396 ret = 1; 05397 break; 05398 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05399 ret++; 05400 } 05401 } 05402 } 05403 05404 closedir(dir); 05405 05406 return ret; 05407 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 13621 of file app_voicemail.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 13621 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 11000 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().
11001 { 11002 struct ast_vm_user svm; 11003 AST_DECLARE_APP_ARGS(arg, 11004 AST_APP_ARG(mbox); 11005 AST_APP_ARG(context); 11006 ); 11007 11008 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11009 11010 if (ast_strlen_zero(arg.mbox)) { 11011 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11012 return -1; 11013 } 11014 11015 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11016 return 0; 11017 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11821 of file app_voicemail.c.
References adsifdn, adsisec, adsiver, append_mailbox(), apply_options_full(), ast_category_browse(), ast_config_option(), ast_copy_string(), ast_debug, ast_dsp_get_threshold_from_settings(), ast_false(), ast_format_str_reduce(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_LOG_DEBUG, AST_LOG_ERROR, ast_malloc, AST_PTHREADT_NULL, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, DEFAULT_LISTEN_CONTROL_FORWARD_KEY, DEFAULT_LISTEN_CONTROL_PAUSE_KEY, DEFAULT_LISTEN_CONTROL_RESTART_KEY, DEFAULT_LISTEN_CONTROL_REVERSE_KEY, DEFAULT_LISTEN_CONTROL_STOP_KEY, DEFAULT_POLL_FREQ, dialcontext, emailbody, emaildateformat, emailsubject, exitcontext, ext_pass_check_cmd, ext_pass_cmd, externnotify, find_or_create(), free_vm_users(), free_vm_zones(), fromstring, globalflags, is_valid_dtmf(), vm_zone::list, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, locale, LOG_ERROR, mailcmd, MAX_NUM_CID_CONTEXTS, maxdeletedmsg, maxgreet, maxlogins, MAXMSG, maxmsg, MAXMSGLIMIT, maxsilence, MINPASSWORD, minpassword, vm_zone::msg_format, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, pagerbody, pagerdateformat, pagerfromstring, pagersubject, passwordlocation, poll_freq, poll_mailboxes, poll_thread, populate_defaults(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, read_password_from_file(), saydurationminfo, SENDMAIL, serveremail, silencethreshold, skipms, smdi_iface, start_poll_thread(), stop_poll_thread(), strsep(), substitute_escapes(), THRESHOLD_SILENCE, userscontext, var, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_FWDURGAUTO, vm_invalid_password, VM_MESSAGEWRAP, vm_mismatch, VM_MOVEHEARD, vm_newpassword, VM_OPERATOR, vm_passchanged, vm_password, VM_PBXSKIP, vm_pls_try_again, vm_prepend_timeout, vm_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SPOOL_DIR, VM_SVMAIL, VM_TEMPGREETWARN, vmfmts, vmmaxsecs, vmminsecs, volgain, and zonetag.
Referenced by load_config().
11822 { 11823 struct ast_vm_user *current; 11824 char *cat; 11825 struct ast_variable *var; 11826 const char *val; 11827 char *q, *stringp, *tmp; 11828 int x; 11829 int tmpadsi[4]; 11830 char secretfn[PATH_MAX] = ""; 11831 11832 #ifdef IMAP_STORAGE 11833 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11834 #endif 11835 /* set audio control prompts */ 11836 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11837 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11838 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11839 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11840 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11841 11842 /* Free all the users structure */ 11843 free_vm_users(); 11844 11845 /* Free all the zones structure */ 11846 free_vm_zones(); 11847 11848 AST_LIST_LOCK(&users); 11849 11850 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11851 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11852 11853 if (cfg) { 11854 /* General settings */ 11855 11856 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11857 val = "default"; 11858 ast_copy_string(userscontext, val, sizeof(userscontext)); 11859 /* Attach voice message to mail message ? */ 11860 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11861 val = "yes"; 11862 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11863 11864 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11865 val = "no"; 11866 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11867 11868 volgain = 0.0; 11869 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11870 sscanf(val, "%30lf", &volgain); 11871 11872 #ifdef ODBC_STORAGE 11873 strcpy(odbc_database, "asterisk"); 11874 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11875 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11876 } 11877 strcpy(odbc_table, "voicemessages"); 11878 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11879 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11880 } 11881 #endif 11882 /* Mail command */ 11883 strcpy(mailcmd, SENDMAIL); 11884 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11885 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11886 11887 maxsilence = 0; 11888 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11889 maxsilence = atoi(val); 11890 if (maxsilence > 0) 11891 maxsilence *= 1000; 11892 } 11893 11894 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11895 maxmsg = MAXMSG; 11896 } else { 11897 maxmsg = atoi(val); 11898 if (maxmsg < 0) { 11899 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11900 maxmsg = MAXMSG; 11901 } else if (maxmsg > MAXMSGLIMIT) { 11902 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11903 maxmsg = MAXMSGLIMIT; 11904 } 11905 } 11906 11907 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11908 maxdeletedmsg = 0; 11909 } else { 11910 if (sscanf(val, "%30d", &x) == 1) 11911 maxdeletedmsg = x; 11912 else if (ast_true(val)) 11913 maxdeletedmsg = MAXMSG; 11914 else 11915 maxdeletedmsg = 0; 11916 11917 if (maxdeletedmsg < 0) { 11918 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11919 maxdeletedmsg = MAXMSG; 11920 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11921 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11922 maxdeletedmsg = MAXMSGLIMIT; 11923 } 11924 } 11925 11926 /* Load date format config for voicemail mail */ 11927 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11928 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11929 } 11930 11931 /* Load date format config for voicemail pager mail */ 11932 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11933 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11934 } 11935 11936 /* External password changing command */ 11937 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11938 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11939 pwdchange = PWDCHANGE_EXTERNAL; 11940 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 11941 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11942 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 11943 } 11944 11945 /* External password validation command */ 11946 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 11947 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 11948 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 11949 } 11950 11951 #ifdef IMAP_STORAGE 11952 /* IMAP server address */ 11953 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 11954 ast_copy_string(imapserver, val, sizeof(imapserver)); 11955 } else { 11956 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 11957 } 11958 /* IMAP server port */ 11959 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 11960 ast_copy_string(imapport, val, sizeof(imapport)); 11961 } else { 11962 ast_copy_string(imapport, "143", sizeof(imapport)); 11963 } 11964 /* IMAP server flags */ 11965 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 11966 ast_copy_string(imapflags, val, sizeof(imapflags)); 11967 } 11968 /* IMAP server master username */ 11969 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 11970 ast_copy_string(authuser, val, sizeof(authuser)); 11971 } 11972 /* IMAP server master password */ 11973 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 11974 ast_copy_string(authpassword, val, sizeof(authpassword)); 11975 } 11976 /* Expunge on exit */ 11977 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 11978 if (ast_false(val)) 11979 expungeonhangup = 0; 11980 else 11981 expungeonhangup = 1; 11982 } else { 11983 expungeonhangup = 1; 11984 } 11985 /* IMAP voicemail folder */ 11986 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 11987 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 11988 } else { 11989 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 11990 } 11991 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 11992 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 11993 } 11994 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 11995 imapgreetings = ast_true(val); 11996 } else { 11997 imapgreetings = 0; 11998 } 11999 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12000 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12001 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12002 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12003 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12004 } else { 12005 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12006 } 12007 12008 /* There is some very unorthodox casting done here. This is due 12009 * to the way c-client handles the argument passed in. It expects a 12010 * void pointer and casts the pointer directly to a long without 12011 * first dereferencing it. */ 12012 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12013 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12014 } else { 12015 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12016 } 12017 12018 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12019 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12020 } else { 12021 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12022 } 12023 12024 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12025 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12026 } else { 12027 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12028 } 12029 12030 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12031 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12032 } else { 12033 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12034 } 12035 12036 /* Increment configuration version */ 12037 imapversion++; 12038 #endif 12039 /* External voicemail notify application */ 12040 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12041 ast_copy_string(externnotify, val, sizeof(externnotify)); 12042 ast_debug(1, "found externnotify: %s\n", externnotify); 12043 } else { 12044 externnotify[0] = '\0'; 12045 } 12046 12047 /* SMDI voicemail notification */ 12048 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12049 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12050 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12051 smdi_iface = ast_smdi_interface_find(val); 12052 } else { 12053 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12054 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12055 } 12056 if (!smdi_iface) { 12057 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12058 } 12059 } 12060 12061 /* Silence treshold */ 12062 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12063 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12064 silencethreshold = atoi(val); 12065 12066 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12067 val = ASTERISK_USERNAME; 12068 ast_copy_string(serveremail, val, sizeof(serveremail)); 12069 12070 vmmaxsecs = 0; 12071 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12072 if (sscanf(val, "%30d", &x) == 1) { 12073 vmmaxsecs = x; 12074 } else { 12075 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12076 } 12077 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12078 static int maxmessage_deprecate = 0; 12079 if (maxmessage_deprecate == 0) { 12080 maxmessage_deprecate = 1; 12081 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12082 } 12083 if (sscanf(val, "%30d", &x) == 1) { 12084 vmmaxsecs = x; 12085 } else { 12086 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12087 } 12088 } 12089 12090 vmminsecs = 0; 12091 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12092 if (sscanf(val, "%30d", &x) == 1) { 12093 vmminsecs = x; 12094 if (maxsilence / 1000 >= vmminsecs) { 12095 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12096 } 12097 } else { 12098 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12099 } 12100 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12101 static int maxmessage_deprecate = 0; 12102 if (maxmessage_deprecate == 0) { 12103 maxmessage_deprecate = 1; 12104 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12105 } 12106 if (sscanf(val, "%30d", &x) == 1) { 12107 vmminsecs = x; 12108 if (maxsilence / 1000 >= vmminsecs) { 12109 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12110 } 12111 } else { 12112 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12113 } 12114 } 12115 12116 val = ast_variable_retrieve(cfg, "general", "format"); 12117 if (!val) { 12118 val = "wav"; 12119 } else { 12120 tmp = ast_strdupa(val); 12121 val = ast_format_str_reduce(tmp); 12122 if (!val) { 12123 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12124 val = "wav"; 12125 } 12126 } 12127 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12128 12129 skipms = 3000; 12130 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12131 if (sscanf(val, "%30d", &x) == 1) { 12132 maxgreet = x; 12133 } else { 12134 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12135 } 12136 } 12137 12138 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12139 if (sscanf(val, "%30d", &x) == 1) { 12140 skipms = x; 12141 } else { 12142 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12143 } 12144 } 12145 12146 maxlogins = 3; 12147 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12148 if (sscanf(val, "%30d", &x) == 1) { 12149 maxlogins = x; 12150 } else { 12151 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12152 } 12153 } 12154 12155 minpassword = MINPASSWORD; 12156 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12157 if (sscanf(val, "%30d", &x) == 1) { 12158 minpassword = x; 12159 } else { 12160 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12161 } 12162 } 12163 12164 /* Force new user to record name ? */ 12165 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12166 val = "no"; 12167 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12168 12169 /* Force new user to record greetings ? */ 12170 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12171 val = "no"; 12172 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12173 12174 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12175 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12176 stringp = ast_strdupa(val); 12177 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12178 if (!ast_strlen_zero(stringp)) { 12179 q = strsep(&stringp, ","); 12180 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12181 q++; 12182 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12183 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12184 } else { 12185 cidinternalcontexts[x][0] = '\0'; 12186 } 12187 } 12188 } 12189 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12190 ast_debug(1, "VM Review Option disabled globally\n"); 12191 val = "no"; 12192 } 12193 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12194 12195 /* Temporary greeting reminder */ 12196 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12197 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12198 val = "no"; 12199 } else { 12200 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12201 } 12202 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12203 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12204 ast_debug(1, "VM next message wrap disabled globally\n"); 12205 val = "no"; 12206 } 12207 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12208 12209 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12210 ast_debug(1, "VM Operator break disabled globally\n"); 12211 val = "no"; 12212 } 12213 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12214 12215 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12216 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12217 val = "no"; 12218 } 12219 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12220 12221 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12222 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12223 val = "no"; 12224 } 12225 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12226 12227 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12228 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12229 val = "yes"; 12230 } 12231 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12232 12233 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12234 ast_debug(1, "Move Heard enabled globally\n"); 12235 val = "yes"; 12236 } 12237 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12238 12239 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12240 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12241 val = "no"; 12242 } 12243 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12244 12245 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12246 ast_debug(1, "Duration info before msg enabled globally\n"); 12247 val = "yes"; 12248 } 12249 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12250 12251 saydurationminfo = 2; 12252 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12253 if (sscanf(val, "%30d", &x) == 1) { 12254 saydurationminfo = x; 12255 } else { 12256 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12257 } 12258 } 12259 12260 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12261 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12262 val = "no"; 12263 } 12264 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12265 12266 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12267 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12268 ast_debug(1, "found dialout context: %s\n", dialcontext); 12269 } else { 12270 dialcontext[0] = '\0'; 12271 } 12272 12273 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12274 ast_copy_string(callcontext, val, sizeof(callcontext)); 12275 ast_debug(1, "found callback context: %s\n", callcontext); 12276 } else { 12277 callcontext[0] = '\0'; 12278 } 12279 12280 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12281 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12282 ast_debug(1, "found operator context: %s\n", exitcontext); 12283 } else { 12284 exitcontext[0] = '\0'; 12285 } 12286 12287 /* load password sounds configuration */ 12288 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12289 ast_copy_string(vm_password, val, sizeof(vm_password)); 12290 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12291 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12292 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12293 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12294 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12295 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12296 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12297 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12298 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12299 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12300 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12301 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12302 } 12303 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12304 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12305 } 12306 /* load configurable audio prompts */ 12307 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12308 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12309 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12310 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12311 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12312 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12313 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12314 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12315 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12316 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12317 12318 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12319 val = "no"; 12320 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12321 12322 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12323 val = "voicemail.conf"; 12324 } 12325 if (!(strcmp(val, "spooldir"))) { 12326 passwordlocation = OPT_PWLOC_SPOOLDIR; 12327 } else { 12328 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12329 } 12330 12331 poll_freq = DEFAULT_POLL_FREQ; 12332 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12333 if (sscanf(val, "%30u", &poll_freq) != 1) { 12334 poll_freq = DEFAULT_POLL_FREQ; 12335 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12336 } 12337 } 12338 12339 poll_mailboxes = 0; 12340 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12341 poll_mailboxes = ast_true(val); 12342 12343 memset(fromstring, 0, sizeof(fromstring)); 12344 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12345 strcpy(charset, "ISO-8859-1"); 12346 if (emailbody) { 12347 ast_free(emailbody); 12348 emailbody = NULL; 12349 } 12350 if (emailsubject) { 12351 ast_free(emailsubject); 12352 emailsubject = NULL; 12353 } 12354 if (pagerbody) { 12355 ast_free(pagerbody); 12356 pagerbody = NULL; 12357 } 12358 if (pagersubject) { 12359 ast_free(pagersubject); 12360 pagersubject = NULL; 12361 } 12362 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12363 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12364 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12365 ast_copy_string(fromstring, val, sizeof(fromstring)); 12366 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12367 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12368 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12369 ast_copy_string(charset, val, sizeof(charset)); 12370 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12371 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12372 for (x = 0; x < 4; x++) { 12373 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12374 } 12375 } 12376 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12377 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12378 for (x = 0; x < 4; x++) { 12379 memcpy(&adsisec[x], &tmpadsi[x], 1); 12380 } 12381 } 12382 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12383 if (atoi(val)) { 12384 adsiver = atoi(val); 12385 } 12386 } 12387 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12388 ast_copy_string(zonetag, val, sizeof(zonetag)); 12389 } 12390 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12391 ast_copy_string(locale, val, sizeof(locale)); 12392 } 12393 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12394 emailsubject = ast_strdup(substitute_escapes(val)); 12395 } 12396 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12397 emailbody = ast_strdup(substitute_escapes(val)); 12398 } 12399 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12400 pagersubject = ast_strdup(substitute_escapes(val)); 12401 } 12402 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12403 pagerbody = ast_strdup(substitute_escapes(val)); 12404 } 12405 12406 /* load mailboxes from users.conf */ 12407 if (ucfg) { 12408 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12409 if (!strcasecmp(cat, "general")) { 12410 continue; 12411 } 12412 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12413 continue; 12414 if ((current = find_or_create(userscontext, cat))) { 12415 populate_defaults(current); 12416 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12417 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12418 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12419 current->passwordlocation = OPT_PWLOC_USERSCONF; 12420 } 12421 12422 switch (current->passwordlocation) { 12423 case OPT_PWLOC_SPOOLDIR: 12424 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12425 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12426 } 12427 } 12428 } 12429 } 12430 12431 /* load mailboxes from voicemail.conf */ 12432 cat = ast_category_browse(cfg, NULL); 12433 while (cat) { 12434 if (strcasecmp(cat, "general")) { 12435 var = ast_variable_browse(cfg, cat); 12436 if (strcasecmp(cat, "zonemessages")) { 12437 /* Process mailboxes in this context */ 12438 while (var) { 12439 append_mailbox(cat, var->name, var->value); 12440 var = var->next; 12441 } 12442 } else { 12443 /* Timezones in this context */ 12444 while (var) { 12445 struct vm_zone *z; 12446 if ((z = ast_malloc(sizeof(*z)))) { 12447 char *msg_format, *tzone; 12448 msg_format = ast_strdupa(var->value); 12449 tzone = strsep(&msg_format, "|,"); 12450 if (msg_format) { 12451 ast_copy_string(z->name, var->name, sizeof(z->name)); 12452 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12453 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12454 AST_LIST_LOCK(&zones); 12455 AST_LIST_INSERT_HEAD(&zones, z, list); 12456 AST_LIST_UNLOCK(&zones); 12457 } else { 12458 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12459 ast_free(z); 12460 } 12461 } else { 12462 AST_LIST_UNLOCK(&users); 12463 return -1; 12464 } 12465 var = var->next; 12466 } 12467 } 12468 } 12469 cat = ast_category_browse(cfg, cat); 12470 } 12471 12472 AST_LIST_UNLOCK(&users); 12473 12474 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12475 start_poll_thread(); 12476 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12477 stop_poll_thread();; 12478 12479 return 0; 12480 } else { 12481 AST_LIST_UNLOCK(&users); 12482 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12483 return 0; 12484 } 12485 }
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 4786 of file app_voicemail.c.
References ast_debug, ast_log(), ast_safe_system(), base_encode(), ast_vm_user::context, create_dirpath(), ENDL, LOG_WARNING, ast_vm_user::mailbox, my_umask, VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.
Referenced by make_email_file().
04787 { 04788 char tmpdir[256], newtmp[256]; 04789 char fname[256]; 04790 char tmpcmd[256]; 04791 int tmpfd = -1; 04792 int soxstatus = 0; 04793 04794 /* Eww. We want formats to tell us their own MIME type */ 04795 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04796 04797 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04798 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04799 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04800 tmpfd = mkstemp(newtmp); 04801 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04802 ast_debug(3, "newtmp: %s\n", newtmp); 04803 if (tmpfd > -1) { 04804 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04805 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04806 attach = newtmp; 04807 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04808 } else { 04809 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04810 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04811 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04812 } 04813 } 04814 } 04815 fprintf(p, "--%s" ENDL, bound); 04816 if (msgnum > -1) 04817 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04818 else 04819 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04820 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04821 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04822 if (msgnum > -1) 04823 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04824 else 04825 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04826 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04827 base_encode(fname, p); 04828 if (last) 04829 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04830 if (tmpfd > -1) { 04831 if (soxstatus == 0) { 04832 unlink(fname); 04833 } 04834 close(tmpfd); 04835 unlink(newtmp); 04836 } 04837 return 0; 04838 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6390 of file app_voicemail.c.
References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available(), ast_adsi_load_session(), and ast_log().
Referenced by vm_authenticate(), and vm_execmain().
06391 { 06392 int x; 06393 if (!ast_adsi_available(chan)) 06394 return; 06395 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06396 if (x < 0) 06397 return; 06398 if (!x) { 06399 if (adsi_load_vmail(chan, useadsi)) { 06400 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06401 return; 06402 } 06403 } else 06404 *useadsi = 1; 06405 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6579 of file app_voicemail.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), and vm_state::curmsg.
Referenced by vm_execmain().
06580 { 06581 int bytes = 0; 06582 unsigned char buf[256]; 06583 unsigned char keys[8]; 06584 06585 int x; 06586 06587 if (!ast_adsi_available(chan)) 06588 return; 06589 06590 /* New meaning for keys */ 06591 for (x = 0; x < 5; x++) 06592 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06593 06594 keys[6] = 0x0; 06595 keys[7] = 0x0; 06596 06597 if (!vms->curmsg) { 06598 /* No prev key, provide "Folder" instead */ 06599 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06600 } 06601 if (vms->curmsg >= vms->lastmsg) { 06602 /* If last message ... */ 06603 if (vms->curmsg) { 06604 /* but not only message, provide "Folder" instead */ 06605 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06606 } else { 06607 /* Otherwise if only message, leave blank */ 06608 keys[3] = 1; 06609 } 06610 } 06611 06612 /* If deleted, show "undeleted" */ 06613 if (vms->deleted[vms->curmsg]) 06614 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06615 06616 /* Except "Exit" */ 06617 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06618 bytes += ast_adsi_set_keys(buf + bytes, keys); 06619 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06620 06621 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06622 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6455 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().
06456 { 06457 unsigned char buf[256]; 06458 int bytes = 0; 06459 unsigned char keys[8]; 06460 int x, y; 06461 06462 if (!ast_adsi_available(chan)) 06463 return; 06464 06465 for (x = 0; x < 5; x++) { 06466 y = ADSI_KEY_APPS + 12 + start + x; 06467 if (y > ADSI_KEY_APPS + 12 + 4) 06468 y = 0; 06469 keys[x] = ADSI_KEY_SKT | y; 06470 } 06471 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06472 keys[6] = 0; 06473 keys[7] = 0; 06474 06475 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06476 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06477 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06478 bytes += ast_adsi_set_keys(buf + bytes, keys); 06479 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06480 06481 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06482 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6727 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().
06728 { 06729 unsigned char buf[256]; 06730 int bytes = 0; 06731 06732 if (!ast_adsi_available(chan)) 06733 return; 06734 bytes += adsi_logo(buf + bytes); 06735 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06736 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06737 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06738 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06739 06740 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06741 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6261 of file app_voicemail.c.
References addesc, ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, adsifdn, adsisec, adsiver, ast_adsi_begin_download(), ast_adsi_data_mode(), ast_adsi_display(), ast_adsi_download_disconnect(), ast_adsi_end_download(), ast_adsi_load_session(), ast_adsi_load_soft_key(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_debug, and mbox().
Referenced by adsi_begin().
06262 { 06263 unsigned char buf[256]; 06264 int bytes = 0; 06265 int x; 06266 char num[5]; 06267 06268 *useadsi = 0; 06269 bytes += ast_adsi_data_mode(buf + bytes); 06270 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06271 06272 bytes = 0; 06273 bytes += adsi_logo(buf); 06274 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06275 #ifdef DISPLAY 06276 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06277 #endif 06278 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06279 bytes += ast_adsi_data_mode(buf + bytes); 06280 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06281 06282 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06283 bytes = 0; 06284 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06285 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06286 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06287 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06288 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06289 return 0; 06290 } 06291 06292 #ifdef DISPLAY 06293 /* Add a dot */ 06294 bytes = 0; 06295 bytes += ast_adsi_logo(buf); 06296 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06297 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06298 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06299 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06300 #endif 06301 bytes = 0; 06302 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06303 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06304 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06305 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06306 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06307 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06308 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06309 06310 #ifdef DISPLAY 06311 /* Add another dot */ 06312 bytes = 0; 06313 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06314 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06315 06316 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06317 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06318 #endif 06319 06320 bytes = 0; 06321 /* These buttons we load but don't use yet */ 06322 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06323 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06324 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06325 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06326 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06327 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06328 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06329 06330 #ifdef DISPLAY 06331 /* Add another dot */ 06332 bytes = 0; 06333 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06334 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06335 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06336 #endif 06337 06338 bytes = 0; 06339 for (x = 0; x < 5; x++) { 06340 snprintf(num, sizeof(num), "%d", x); 06341 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06342 } 06343 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06344 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06345 06346 #ifdef DISPLAY 06347 /* Add another dot */ 06348 bytes = 0; 06349 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06350 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06351 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06352 #endif 06353 06354 if (ast_adsi_end_download(chan)) { 06355 bytes = 0; 06356 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06357 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06358 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06359 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06360 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06361 return 0; 06362 } 06363 bytes = 0; 06364 bytes += ast_adsi_download_disconnect(buf + bytes); 06365 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06366 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06367 06368 ast_debug(1, "Done downloading scripts...\n"); 06369 06370 #ifdef DISPLAY 06371 /* Add last dot */ 06372 bytes = 0; 06373 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06374 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06375 #endif 06376 ast_debug(1, "Restarting session...\n"); 06377 06378 bytes = 0; 06379 /* Load the session now */ 06380 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06381 *useadsi = 1; 06382 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06383 } else 06384 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06385 06386 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06387 return 0; 06388 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6407 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().
06408 { 06409 unsigned char buf[256]; 06410 int bytes = 0; 06411 unsigned char keys[8]; 06412 int x; 06413 if (!ast_adsi_available(chan)) 06414 return; 06415 06416 for (x = 0; x < 8; x++) 06417 keys[x] = 0; 06418 /* Set one key for next */ 06419 keys[3] = ADSI_KEY_APPS + 3; 06420 06421 bytes += adsi_logo(buf + bytes); 06422 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06423 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06424 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06425 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06426 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06427 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06428 bytes += ast_adsi_set_keys(buf + bytes, keys); 06429 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06430 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06431 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6253 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().
06254 { 06255 int bytes = 0; 06256 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06257 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06258 return bytes; 06259 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6484 of file app_voicemail.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), ast_copy_string(), ast_strlen_zero(), buf1, buf2, vm_state::curmsg, vm_state::fn, name, and strsep().
Referenced by play_message(), and vm_execmain().
06485 { 06486 int bytes = 0; 06487 unsigned char buf[256]; 06488 char buf1[256], buf2[256]; 06489 char fn2[PATH_MAX]; 06490 06491 char cid[256] = ""; 06492 char *val; 06493 char *name, *num; 06494 char datetime[21] = ""; 06495 FILE *f; 06496 06497 unsigned char keys[8]; 06498 06499 int x; 06500 06501 if (!ast_adsi_available(chan)) 06502 return; 06503 06504 /* Retrieve important info */ 06505 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06506 f = fopen(fn2, "r"); 06507 if (f) { 06508 while (!feof(f)) { 06509 if (!fgets((char *) buf, sizeof(buf), f)) { 06510 continue; 06511 } 06512 if (!feof(f)) { 06513 char *stringp = NULL; 06514 stringp = (char *) buf; 06515 strsep(&stringp, "="); 06516 val = strsep(&stringp, "="); 06517 if (!ast_strlen_zero(val)) { 06518 if (!strcmp((char *) buf, "callerid")) 06519 ast_copy_string(cid, val, sizeof(cid)); 06520 if (!strcmp((char *) buf, "origdate")) 06521 ast_copy_string(datetime, val, sizeof(datetime)); 06522 } 06523 } 06524 } 06525 fclose(f); 06526 } 06527 /* New meaning for keys */ 06528 for (x = 0; x < 5; x++) 06529 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06530 keys[6] = 0x0; 06531 keys[7] = 0x0; 06532 06533 if (!vms->curmsg) { 06534 /* No prev key, provide "Folder" instead */ 06535 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06536 } 06537 if (vms->curmsg >= vms->lastmsg) { 06538 /* If last message ... */ 06539 if (vms->curmsg) { 06540 /* but not only message, provide "Folder" instead */ 06541 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06542 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06543 06544 } else { 06545 /* Otherwise if only message, leave blank */ 06546 keys[3] = 1; 06547 } 06548 } 06549 06550 if (!ast_strlen_zero(cid)) { 06551 ast_callerid_parse(cid, &name, &num); 06552 if (!name) 06553 name = num; 06554 } else 06555 name = "Unknown Caller"; 06556 06557 /* If deleted, show "undeleted" */ 06558 06559 if (vms->deleted[vms->curmsg]) 06560 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06561 06562 /* Except "Exit" */ 06563 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06564 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06565 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06566 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06567 06568 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06569 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06570 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06571 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06572 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06573 bytes += ast_adsi_set_keys(buf + bytes, keys); 06574 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06575 06576 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06577 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6433 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().
06434 { 06435 unsigned char buf[256]; 06436 int bytes = 0; 06437 unsigned char keys[8]; 06438 int x; 06439 if (!ast_adsi_available(chan)) 06440 return; 06441 06442 for (x = 0; x < 8; x++) 06443 keys[x] = 0; 06444 /* Set one key for next */ 06445 keys[3] = ADSI_KEY_APPS + 3; 06446 06447 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06448 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06449 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06450 bytes += ast_adsi_set_keys(buf + bytes, keys); 06451 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06452 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06453 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6624 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().
06625 { 06626 unsigned char buf[256] = ""; 06627 char buf1[256] = "", buf2[256] = ""; 06628 int bytes = 0; 06629 unsigned char keys[8]; 06630 int x; 06631 06632 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06633 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06634 if (!ast_adsi_available(chan)) 06635 return; 06636 if (vms->newmessages) { 06637 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06638 if (vms->oldmessages) { 06639 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06640 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06641 } else { 06642 snprintf(buf2, sizeof(buf2), "%s.", newm); 06643 } 06644 } else if (vms->oldmessages) { 06645 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06646 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06647 } else { 06648 strcpy(buf1, "You have no messages."); 06649 buf2[0] = ' '; 06650 buf2[1] = '\0'; 06651 } 06652 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06653 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06654 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06655 06656 for (x = 0; x < 6; x++) 06657 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06658 keys[6] = 0; 06659 keys[7] = 0; 06660 06661 /* Don't let them listen if there are none */ 06662 if (vms->lastmsg < 0) 06663 keys[0] = 1; 06664 bytes += ast_adsi_set_keys(buf + bytes, keys); 06665 06666 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06667 06668 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06669 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6671 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().
06672 { 06673 unsigned char buf[256] = ""; 06674 char buf1[256] = "", buf2[256] = ""; 06675 int bytes = 0; 06676 unsigned char keys[8]; 06677 int x; 06678 06679 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06680 06681 if (!ast_adsi_available(chan)) 06682 return; 06683 06684 /* Original command keys */ 06685 for (x = 0; x < 6; x++) 06686 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06687 06688 keys[6] = 0; 06689 keys[7] = 0; 06690 06691 if ((vms->lastmsg + 1) < 1) 06692 keys[0] = 0; 06693 06694 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06695 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06696 06697 if (vms->lastmsg + 1) 06698 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06699 else 06700 strcpy(buf2, "no messages."); 06701 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06702 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06703 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06704 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06705 bytes += ast_adsi_set_keys(buf + bytes, keys); 06706 06707 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06708 06709 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06710 06711 }
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 13183 of file app_voicemail.c.
References ast_callerid_parse(), ast_config_destroy(), ast_config_load, ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), name, play_message_callerid(), play_message_datetime(), RETRIEVE, vm_state::starting, and wait_file().
Referenced by vm_execmain().
13184 { 13185 int res = 0; 13186 char filename[PATH_MAX]; 13187 struct ast_config *msg_cfg = NULL; 13188 const char *origtime, *context; 13189 char *name, *num; 13190 int retries = 0; 13191 char *cid; 13192 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13193 13194 vms->starting = 0; 13195 13196 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13197 13198 /* Retrieve info from VM attribute file */ 13199 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13200 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13201 msg_cfg = ast_config_load(filename, config_flags); 13202 DISPOSE(vms->curdir, vms->curmsg); 13203 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 13204 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13205 return 0; 13206 } 13207 13208 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13209 ast_config_destroy(msg_cfg); 13210 return 0; 13211 } 13212 13213 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13214 13215 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13216 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13217 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13218 switch (option) { 13219 case 3: /* Play message envelope */ 13220 if (!res) 13221 res = play_message_datetime(chan, vmu, origtime, filename); 13222 if (!res) 13223 res = play_message_callerid(chan, vms, cid, context, 0); 13224 13225 res = 't'; 13226 break; 13227 13228 case 2: /* Call back */ 13229 13230 if (ast_strlen_zero(cid)) 13231 break; 13232 13233 ast_callerid_parse(cid, &name, &num); 13234 while ((res > -1) && (res != 't')) { 13235 switch (res) { 13236 case '1': 13237 if (num) { 13238 /* Dial the CID number */ 13239 res = dialout(chan, vmu, num, vmu->callback); 13240 if (res) { 13241 ast_config_destroy(msg_cfg); 13242 return 9; 13243 } 13244 } else { 13245 res = '2'; 13246 } 13247 break; 13248 13249 case '2': 13250 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13251 if (!ast_strlen_zero(vmu->dialout)) { 13252 res = dialout(chan, vmu, NULL, vmu->dialout); 13253 if (res) { 13254 ast_config_destroy(msg_cfg); 13255 return 9; 13256 } 13257 } else { 13258 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13259 res = ast_play_and_wait(chan, "vm-sorry"); 13260 } 13261 ast_config_destroy(msg_cfg); 13262 return res; 13263 case '*': 13264 res = 't'; 13265 break; 13266 case '3': 13267 case '4': 13268 case '5': 13269 case '6': 13270 case '7': 13271 case '8': 13272 case '9': 13273 case '0': 13274 13275 res = ast_play_and_wait(chan, "vm-sorry"); 13276 retries++; 13277 break; 13278 default: 13279 if (num) { 13280 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13281 res = ast_play_and_wait(chan, "vm-num-i-have"); 13282 if (!res) 13283 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13284 if (!res) 13285 res = ast_play_and_wait(chan, "vm-tocallnum"); 13286 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13287 if (!ast_strlen_zero(vmu->dialout)) { 13288 if (!res) 13289 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13290 } 13291 } else { 13292 res = ast_play_and_wait(chan, "vm-nonumber"); 13293 if (!ast_strlen_zero(vmu->dialout)) { 13294 if (!res) 13295 res = ast_play_and_wait(chan, "vm-toenternumber"); 13296 } 13297 } 13298 if (!res) { 13299 res = ast_play_and_wait(chan, "vm-star-cancel"); 13300 } 13301 if (!res) { 13302 res = ast_waitfordigit(chan, 6000); 13303 } 13304 if (!res) { 13305 retries++; 13306 if (retries > 3) { 13307 res = 't'; 13308 } 13309 } 13310 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13311 break; 13312 13313 } 13314 if (res == 't') 13315 res = 0; 13316 else if (res == '*') 13317 res = -1; 13318 } 13319 break; 13320 13321 case 1: /* Reply */ 13322 /* Send reply directly to sender */ 13323 if (ast_strlen_zero(cid)) 13324 break; 13325 13326 ast_callerid_parse(cid, &name, &num); 13327 if (!num) { 13328 ast_verb(3, "No CID number available, no reply sent\n"); 13329 if (!res) 13330 res = ast_play_and_wait(chan, "vm-nonumber"); 13331 ast_config_destroy(msg_cfg); 13332 return res; 13333 } else { 13334 struct ast_vm_user vmu2; 13335 if (find_user(&vmu2, vmu->context, num)) { 13336 struct leave_vm_options leave_options; 13337 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13338 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13339 13340 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13341 13342 memset(&leave_options, 0, sizeof(leave_options)); 13343 leave_options.record_gain = record_gain; 13344 res = leave_voicemail(chan, mailbox, &leave_options); 13345 if (!res) 13346 res = 't'; 13347 ast_config_destroy(msg_cfg); 13348 return res; 13349 } else { 13350 /* Sender has no mailbox, can't reply */ 13351 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13352 ast_play_and_wait(chan, "vm-nobox"); 13353 res = 't'; 13354 ast_config_destroy(msg_cfg); 13355 return res; 13356 } 13357 } 13358 res = 0; 13359 13360 break; 13361 } 13362 13363 #ifndef IMAP_STORAGE 13364 ast_config_destroy(msg_cfg); 13365 13366 if (!res) { 13367 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13368 vms->heard[msg] = 1; 13369 res = wait_file(chan, vms, vms->fn); 13370 } 13371 #endif 13372 return res; 13373 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10727 of file app_voicemail.c.
References apply_options(), ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, inboxcount2(), LOG_WARNING, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, ast_vm_user::pager, ast_vm_user::password, ast_vm_user::passwordlocation, populate_defaults(), queue_mwi_event(), read_password_from_file(), strsep(), and VM_SPOOL_DIR.
Referenced by actual_load_config().
10728 { 10729 /* Assumes lock is already held */ 10730 char *tmp; 10731 char *stringp; 10732 char *s; 10733 struct ast_vm_user *vmu; 10734 char *mailbox_full; 10735 int new = 0, old = 0, urgent = 0; 10736 char secretfn[PATH_MAX] = ""; 10737 10738 tmp = ast_strdupa(data); 10739 10740 if (!(vmu = find_or_create(context, box))) 10741 return -1; 10742 10743 populate_defaults(vmu); 10744 10745 stringp = tmp; 10746 if ((s = strsep(&stringp, ","))) { 10747 if (!ast_strlen_zero(s) && s[0] == '*') { 10748 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10749 "\n\tmust be reset in voicemail.conf.\n", box); 10750 } 10751 /* assign password regardless of validity to prevent NULL password from being assigned */ 10752 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10753 } 10754 if (stringp && (s = strsep(&stringp, ","))) { 10755 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10756 } 10757 if (stringp && (s = strsep(&stringp, ","))) { 10758 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10759 } 10760 if (stringp && (s = strsep(&stringp, ","))) { 10761 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10762 } 10763 if (stringp && (s = strsep(&stringp, ","))) { 10764 apply_options(vmu, s); 10765 } 10766 10767 switch (vmu->passwordlocation) { 10768 case OPT_PWLOC_SPOOLDIR: 10769 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10770 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10771 } 10772 10773 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 10774 strcpy(mailbox_full, box); 10775 strcat(mailbox_full, "@"); 10776 strcat(mailbox_full, context); 10777 10778 inboxcount2(mailbox_full, &urgent, &new, &old); 10779 queue_mwi_event(mailbox_full, urgent, new, old); 10780 10781 return 0; 10782 }
static void apply_option | ( | struct ast_vm_user * | vmu, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Sets a a specific property value.
vmu | The voicemail user object to work with. | |
var | The name of the property to be set. | |
value | The value to be set to the property. |
Definition at line 1056 of file app_voicemail.c.
References apply_options(), ast_copy_string(), ast_log(), AST_LOG_WARNING, ast_set2_flag, ast_strdup, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, ast_vm_user::language, ast_vm_user::locale, LOG_WARNING, ast_vm_user::maxdeletedmsg, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::maxsecs, ast_vm_user::minsecs, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, ast_vm_user::serveremail, substitute_escapes(), VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by apply_options().
01057 { 01058 int x; 01059 if (!strcasecmp(var, "attach")) { 01060 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01061 } else if (!strcasecmp(var, "attachfmt")) { 01062 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01063 } else if (!strcasecmp(var, "serveremail")) { 01064 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01065 } else if (!strcasecmp(var, "emailbody")) { 01066 vmu->emailbody = ast_strdup(substitute_escapes(value)); 01067 } else if (!strcasecmp(var, "emailsubject")) { 01068 vmu->emailsubject = ast_strdup(substitute_escapes(value)); 01069 } else if (!strcasecmp(var, "language")) { 01070 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01071 } else if (!strcasecmp(var, "tz")) { 01072 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01073 } else if (!strcasecmp(var, "locale")) { 01074 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01075 #ifdef IMAP_STORAGE 01076 } else if (!strcasecmp(var, "imapuser")) { 01077 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01078 vmu->imapversion = imapversion; 01079 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01080 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01081 vmu->imapversion = imapversion; 01082 } else if (!strcasecmp(var, "imapfolder")) { 01083 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01084 } else if (!strcasecmp(var, "imapvmshareid")) { 01085 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01086 vmu->imapversion = imapversion; 01087 #endif 01088 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01089 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01090 } else if (!strcasecmp(var, "saycid")){ 01091 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01092 } else if (!strcasecmp(var, "sendvoicemail")){ 01093 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01094 } else if (!strcasecmp(var, "review")){ 01095 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01096 } else if (!strcasecmp(var, "tempgreetwarn")){ 01097 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01098 } else if (!strcasecmp(var, "messagewrap")){ 01099 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01100 } else if (!strcasecmp(var, "operator")) { 01101 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01102 } else if (!strcasecmp(var, "envelope")){ 01103 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01104 } else if (!strcasecmp(var, "moveheard")){ 01105 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01106 } else if (!strcasecmp(var, "sayduration")){ 01107 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01108 } else if (!strcasecmp(var, "saydurationm")){ 01109 if (sscanf(value, "%30d", &x) == 1) { 01110 vmu->saydurationm = x; 01111 } else { 01112 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01113 } 01114 } else if (!strcasecmp(var, "forcename")){ 01115 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01116 } else if (!strcasecmp(var, "forcegreetings")){ 01117 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01118 } else if (!strcasecmp(var, "callback")) { 01119 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01120 } else if (!strcasecmp(var, "dialout")) { 01121 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01122 } else if (!strcasecmp(var, "exitcontext")) { 01123 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01124 } else if (!strcasecmp(var, "minsecs")) { 01125 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01126 vmu->minsecs = x; 01127 } else { 01128 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01129 vmu->minsecs = vmminsecs; 01130 } 01131 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01132 vmu->maxsecs = atoi(value); 01133 if (vmu->maxsecs <= 0) { 01134 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01135 vmu->maxsecs = vmmaxsecs; 01136 } else { 01137 vmu->maxsecs = atoi(value); 01138 } 01139 if (!strcasecmp(var, "maxmessage")) 01140 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01141 } else if (!strcasecmp(var, "maxmsg")) { 01142 vmu->maxmsg = atoi(value); 01143 /* Accept maxmsg=0 (Greetings only voicemail) */ 01144 if (vmu->maxmsg < 0) { 01145 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01146 vmu->maxmsg = MAXMSG; 01147 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01148 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01149 vmu->maxmsg = MAXMSGLIMIT; 01150 } 01151 } else if (!strcasecmp(var, "nextaftercmd")) { 01152 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01153 } else if (!strcasecmp(var, "backupdeleted")) { 01154 if (sscanf(value, "%30d", &x) == 1) 01155 vmu->maxdeletedmsg = x; 01156 else if (ast_true(value)) 01157 vmu->maxdeletedmsg = MAXMSG; 01158 else 01159 vmu->maxdeletedmsg = 0; 01160 01161 if (vmu->maxdeletedmsg < 0) { 01162 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01163 vmu->maxdeletedmsg = MAXMSG; 01164 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01165 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01166 vmu->maxdeletedmsg = MAXMSGLIMIT; 01167 } 01168 } else if (!strcasecmp(var, "volgain")) { 01169 sscanf(value, "%30lf", &vmu->volgain); 01170 } else if (!strcasecmp(var, "passwordlocation")) { 01171 if (!strcasecmp(value, "spooldir")) { 01172 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01173 } else { 01174 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01175 } 01176 } else if (!strcasecmp(var, "options")) { 01177 apply_options(vmu, value); 01178 } 01179 }
static void apply_options | ( | struct ast_vm_user * | vmu, | |
const char * | options | |||
) | [static] |
Destructively Parse options and apply.
Definition at line 1297 of file app_voicemail.c.
References apply_option(), ast_strdupa, strsep(), value, and var.
Referenced by append_mailbox(), apply_option(), and AST_TEST_DEFINE().
01298 { 01299 char *stringp; 01300 char *s; 01301 char *var, *value; 01302 stringp = ast_strdupa(options); 01303 while ((s = strsep(&stringp, "|"))) { 01304 value = s; 01305 if ((var = strsep(&value, "=")) && value) { 01306 apply_option(vmu, var, value); 01307 } 01308 } 01309 }
static void apply_options_full | ( | struct ast_vm_user * | retval, | |
struct ast_variable * | var | |||
) | [static] |
Loads the options specific to a voicemail user.
This is called when a vm_user structure is being set up, such as from load_options.
Definition at line 1316 of file app_voicemail.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), LOG_WARNING, ast_vm_user::mailbox, ast_vm_user::password, and var.
Referenced by actual_load_config(), and find_user_realtime().
01317 { 01318 for (; var; var = var->next) { 01319 if (!strcasecmp(var->name, "vmsecret")) { 01320 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01321 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01322 if (ast_strlen_zero(retval->password)) { 01323 if (!ast_strlen_zero(var->value) && var->value[0] == '*') { 01324 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 01325 "\n\tmust be reset in voicemail.conf.\n", retval->mailbox); 01326 } else { 01327 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01328 } 01329 } 01330 } else if (!strcasecmp(var->name, "uniqueid")) { 01331 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01332 } else if (!strcasecmp(var->name, "pager")) { 01333 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01334 } else if (!strcasecmp(var->name, "email")) { 01335 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01336 } else if (!strcasecmp(var->name, "fullname")) { 01337 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01338 } else if (!strcasecmp(var->name, "context")) { 01339 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01340 } else if (!strcasecmp(var->name, "emailsubject")) { 01341 ast_free(retval->emailsubject); 01342 retval->emailsubject = ast_strdup(substitute_escapes(var->value)); 01343 } else if (!strcasecmp(var->name, "emailbody")) { 01344 ast_free(retval->emailbody); 01345 retval->emailbody = ast_strdup(substitute_escapes(var->value)); 01346 #ifdef IMAP_STORAGE 01347 } else if (!strcasecmp(var->name, "imapuser")) { 01348 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01349 retval->imapversion = imapversion; 01350 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01351 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01352 retval->imapversion = imapversion; 01353 } else if (!strcasecmp(var->name, "imapfolder")) { 01354 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01355 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01356 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01357 retval->imapversion = imapversion; 01358 #endif 01359 } else 01360 apply_option(retval, var->name, var->value); 01361 } 01362 }
AST_DATA_STRUCTURE | ( | vm_zone | , | |
DATA_EXPORT_VM_ZONES | ||||
) |
AST_DATA_STRUCTURE | ( | ast_vm_user | , | |
DATA_EXPORT_VM_USERS | ||||
) |
static const char* ast_str_encode_mime | ( | struct ast_str ** | end, | |
ssize_t | maxlen, | |||
const char * | start, | |||
size_t | preamble, | |||
size_t | postamble | |||
) | [static] |
Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters.
Additionally, if the encoded string would exceed the MIME limit of 76 characters per line, then the encoding will be broken up into multiple sections, separated by a space character, in order to facilitate breaking up the associated header across multiple lines.
end | An expandable buffer for holding the result | |
maxlen | Always zero, but see |
start | A string to be encoded | |
preamble | The length of the first line already used for this string, to ensure that each line maintains a maximum length of 76 chars. | |
postamble | the length of any additional characters appended to the line, used to ensure proper field wrapping. |
The | encoded string. |
Definition at line 4461 of file app_voicemail.c.
References ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), and charset.
04462 { 04463 struct ast_str *tmp = ast_str_alloca(80); 04464 int first_section = 1; 04465 04466 ast_str_reset(*end); 04467 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04468 for (; *start; start++) { 04469 int need_encoding = 0; 04470 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04471 need_encoding = 1; 04472 } 04473 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04474 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04475 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04476 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04477 /* Start new line */ 04478 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04479 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04480 first_section = 0; 04481 } 04482 if (need_encoding && *start == ' ') { 04483 ast_str_append(&tmp, -1, "_"); 04484 } else if (need_encoding) { 04485 ast_str_append(&tmp, -1, "=%hhX", *start); 04486 } else { 04487 ast_str_append(&tmp, -1, "%c", *start); 04488 } 04489 } 04490 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04491 return ast_str_buffer(*end); 04492 }
static const char* ast_str_quote | ( | struct ast_str ** | buf, | |
ssize_t | maxlen, | |||
const char * | from | |||
) | [static] |
Wraps a character sequence in double quotes, escaping occurences of quotes within the string.
from | The string to work with. | |
buf | The buffer into which to write the modified quoted string. | |
maxlen | Always zero, but see |
Definition at line 4389 of file app_voicemail.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
04390 { 04391 const char *ptr; 04392 04393 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04394 ast_str_set(buf, maxlen, "\""); 04395 for (ptr = from; *ptr; ptr++) { 04396 if (*ptr == '"' || *ptr == '\\') { 04397 ast_str_append(buf, maxlen, "\\%c", *ptr); 04398 } else { 04399 ast_str_append(buf, maxlen, "%c", *ptr); 04400 } 04401 } 04402 ast_str_append(buf, maxlen, "\""); 04403 04404 return ast_str_buffer(*buf); 04405 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10784 of file app_voicemail.c.
References apply_options(), ast_calloc, ast_set_flag, AST_TEST_FAIL, ast_test_flag, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, free_user(), OPT_PWLOC_SPOOLDIR, populate_defaults(), TEST_EXECUTE, TEST_INIT, VM_ALLOCED, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SKIPAFTERCMD, VM_SVMAIL, and VM_TEMPGREETWARN.
10785 { 10786 int res = 0; 10787 struct ast_vm_user *vmu; 10788 /* language parameter seems to only be used for display in manager action */ 10789 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10790 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10791 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10792 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10793 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10794 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10795 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10796 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10797 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10798 #ifdef IMAP_STORAGE 10799 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10800 "imapfolder=INBOX|imapvmshareid=6000"; 10801 #endif 10802 10803 switch (cmd) { 10804 case TEST_INIT: 10805 info->name = "vmuser"; 10806 info->category = "/apps/app_voicemail/"; 10807 info->summary = "Vmuser unit test"; 10808 info->description = 10809 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10810 return AST_TEST_NOT_RUN; 10811 case TEST_EXECUTE: 10812 break; 10813 } 10814 10815 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10816 return AST_TEST_NOT_RUN; 10817 } 10818 ast_set_flag(vmu, VM_ALLOCED); 10819 populate_defaults(vmu); 10820 10821 apply_options(vmu, options_string); 10822 10823 if (!ast_test_flag(vmu, VM_ATTACH)) { 10824 ast_test_status_update(test, "Parse failure for attach option\n"); 10825 res = 1; 10826 } 10827 if (strcasecmp(vmu->attachfmt, "wav49")) { 10828 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10829 res = 1; 10830 } 10831 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10832 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10833 res = 1; 10834 } 10835 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10836 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10837 res = 1; 10838 } 10839 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10840 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10841 res = 1; 10842 } 10843 if (strcasecmp(vmu->zonetag, "central")) { 10844 ast_test_status_update(test, "Parse failure for tz option\n"); 10845 res = 1; 10846 } 10847 if (!ast_test_flag(vmu, VM_DELETE)) { 10848 ast_test_status_update(test, "Parse failure for delete option\n"); 10849 res = 1; 10850 } 10851 if (!ast_test_flag(vmu, VM_SAYCID)) { 10852 ast_test_status_update(test, "Parse failure for saycid option\n"); 10853 res = 1; 10854 } 10855 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10856 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10857 res = 1; 10858 } 10859 if (!ast_test_flag(vmu, VM_REVIEW)) { 10860 ast_test_status_update(test, "Parse failure for review option\n"); 10861 res = 1; 10862 } 10863 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10864 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10865 res = 1; 10866 } 10867 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10868 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10869 res = 1; 10870 } 10871 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10872 ast_test_status_update(test, "Parse failure for operator option\n"); 10873 res = 1; 10874 } 10875 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10876 ast_test_status_update(test, "Parse failure for envelope option\n"); 10877 res = 1; 10878 } 10879 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10880 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10881 res = 1; 10882 } 10883 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10884 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10885 res = 1; 10886 } 10887 if (vmu->saydurationm != 5) { 10888 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10889 res = 1; 10890 } 10891 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10892 ast_test_status_update(test, "Parse failure for forcename option\n"); 10893 res = 1; 10894 } 10895 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10896 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10897 res = 1; 10898 } 10899 if (strcasecmp(vmu->callback, "somecontext")) { 10900 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10901 res = 1; 10902 } 10903 if (strcasecmp(vmu->dialout, "somecontext2")) { 10904 ast_test_status_update(test, "Parse failure for dialout option\n"); 10905 res = 1; 10906 } 10907 if (strcasecmp(vmu->exit, "somecontext3")) { 10908 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10909 res = 1; 10910 } 10911 if (vmu->minsecs != 10) { 10912 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10913 res = 1; 10914 } 10915 if (vmu->maxsecs != 100) { 10916 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10917 res = 1; 10918 } 10919 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10920 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10921 res = 1; 10922 } 10923 if (vmu->maxdeletedmsg != 50) { 10924 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10925 res = 1; 10926 } 10927 if (vmu->volgain != 1.3) { 10928 ast_test_status_update(test, "Parse failure for volgain option\n"); 10929 res = 1; 10930 } 10931 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10932 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10933 res = 1; 10934 } 10935 #ifdef IMAP_STORAGE 10936 apply_options(vmu, option_string2); 10937 10938 if (strcasecmp(vmu->imapuser, "imapuser")) { 10939 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10940 res = 1; 10941 } 10942 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10943 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10944 res = 1; 10945 } 10946 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10947 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10948 res = 1; 10949 } 10950 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10951 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10952 res = 1; 10953 } 10954 #endif 10955 10956 free_user(vmu); 10957 return res ? AST_TEST_FAIL : AST_TEST_PASS; 10958 }
static int base_encode | ( | char * | filename, | |
FILE * | so | |||
) | [static] |
Performs a base 64 encode algorithm on the contents of a File.
filename | The path to the file to be encoded. Must be readable, file is opened in read mode. | |
so | A FILE handle to the output file to receive the base 64 encoded contents of the input file, identified by filename. |
Definition at line 4265 of file app_voicemail.c.
References ast_log(), BASEMAXINLINE, ENDL, errno, inchar(), and ochar().
04266 { 04267 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04268 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04269 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04270 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04271 int i, hiteof = 0; 04272 FILE *fi; 04273 struct baseio bio; 04274 04275 memset(&bio, 0, sizeof(bio)); 04276 bio.iocp = BASEMAXINLINE; 04277 04278 if (!(fi = fopen(filename, "rb"))) { 04279 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04280 return -1; 04281 } 04282 04283 while (!hiteof){ 04284 unsigned char igroup[3], ogroup[4]; 04285 int c, n; 04286 04287 memset(igroup, 0, sizeof(igroup)); 04288 04289 for (n = 0; n < 3; n++) { 04290 if ((c = inchar(&bio, fi)) == EOF) { 04291 hiteof = 1; 04292 break; 04293 } 04294 04295 igroup[n] = (unsigned char) c; 04296 } 04297 04298 if (n > 0) { 04299 ogroup[0]= dtable[igroup[0] >> 2]; 04300 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04301 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04302 ogroup[3]= dtable[igroup[2] & 0x3F]; 04303 04304 if (n < 3) { 04305 ogroup[3] = '='; 04306 04307 if (n < 2) 04308 ogroup[2] = '='; 04309 } 04310 04311 for (i = 0; i < 4; i++) 04312 ochar(&bio, ogroup[i], so); 04313 } 04314 } 04315 04316 fclose(fi); 04317 04318 if (fputs(ENDL, so) == EOF) { 04319 return 0; 04320 } 04321 04322 return 1; 04323 }
static int change_password_realtime | ( | struct ast_vm_user * | vmu, | |
const char * | password | |||
) | [static] |
Performs a change of the voicemail passowrd in the realtime engine.
vmu | The voicemail user to change the password for. | |
password | The new value to be set to the password for this user. |
Definition at line 1275 of file app_voicemail.c.
References ast_copy_string(), ast_realtime_require_field(), ast_test_suite_event_notify, ast_update2_realtime(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, RQ_CHAR, and SENTINEL.
Referenced by vm_change_password().
01276 { 01277 int res = -1; 01278 if (!strcmp(vmu->password, password)) { 01279 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01280 return 0; 01281 } 01282 01283 if (strlen(password) > 10) { 01284 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01285 } 01286 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01287 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime"); 01288 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01289 res = 0; 01290 } 01291 return res; 01292 }
static int check_mime | ( | const char * | str | ) | [static] |
Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean.
Definition at line 4434 of file app_voicemail.c.
04435 { 04436 for (; *str; str++) { 04437 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 04438 return 1; 04439 } 04440 } 04441 return 0; 04442 }
static int check_password | ( | struct ast_vm_user * | vmu, | |
char * | password | |||
) | [static] |
Check that password meets minimum required length.
vmu | The voicemail user to change the password for. | |
password | The password string to check |
Definition at line 1234 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_DEBUG, AST_LOG_NOTICE, AST_LOG_WARNING, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and vm_check_password_shell().
Referenced by network_thread(), vm_newuser(), and vm_options().
01235 { 01236 /* check minimum length */ 01237 if (strlen(password) < minpassword) 01238 return 1; 01239 /* check that password does not contain '*' character */ 01240 if (!ast_strlen_zero(password) && password[0] == '*') 01241 return 1; 01242 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01243 char cmd[255], buf[255]; 01244 01245 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01246 01247 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01248 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01249 ast_debug(5, "Result: %s\n", buf); 01250 if (!strncasecmp(buf, "VALID", 5)) { 01251 ast_debug(3, "Passed password check: '%s'\n", buf); 01252 return 0; 01253 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01254 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01255 return 0; 01256 } else { 01257 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01258 return 1; 01259 } 01260 } 01261 } 01262 return 0; 01263 }
static int close_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 7930 of file app_voicemail.c.
References ast_check_realtime(), ast_log(), AST_LOG_NOTICE, ast_test_flag, 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, last_message_index(), vm_state::lastmsg, ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, RENAME, save_to_folder(), vm_lock_path(), and VM_MOVEHEARD.
Referenced by vm_execmain().
07931 { 07932 int x = 0; 07933 07934 #ifndef IMAP_STORAGE 07935 int last_msg_idx; 07936 int res = 0, nummsg; 07937 char fn2[PATH_MAX]; 07938 #endif 07939 07940 if (vms->lastmsg <= -1) { 07941 goto done; 07942 } 07943 07944 vms->curmsg = -1; 07945 #ifndef IMAP_STORAGE 07946 /* Get the deleted messages fixed */ 07947 if (vm_lock_path(vms->curdir)) { 07948 return ERROR_LOCK_PATH; 07949 } 07950 07951 /* update count as message may have arrived while we've got mailbox open */ 07952 last_msg_idx = last_message_index(vmu, vms->curdir); 07953 if (last_msg_idx != vms->lastmsg) { 07954 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 07955 } 07956 07957 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 07958 for (x = 0; x < last_msg_idx + 1; x++) { 07959 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07960 /* Save this message. It's not in INBOX or hasn't been heard */ 07961 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07962 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 07963 break; 07964 } 07965 vms->curmsg++; 07966 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 07967 if (strcmp(vms->fn, fn2)) { 07968 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07969 } 07970 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07971 /* Move to old folder before deleting */ 07972 res = save_to_folder(vmu, vms, x, 1); 07973 if (res == ERROR_LOCK_PATH) { 07974 /* If save failed do not delete the message */ 07975 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 07976 vms->deleted[x] = 0; 07977 vms->heard[x] = 0; 07978 --x; 07979 } 07980 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 07981 /* Move to deleted folder */ 07982 res = save_to_folder(vmu, vms, x, 10); 07983 if (res == ERROR_LOCK_PATH) { 07984 /* If save failed do not delete the message */ 07985 vms->deleted[x] = 0; 07986 vms->heard[x] = 0; 07987 --x; 07988 } 07989 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 07990 /* If realtime storage enabled - we should explicitly delete this message, 07991 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 07992 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07993 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 07994 DELETE(vms->curdir, x, vms->fn, vmu); 07995 } 07996 } 07997 } 07998 07999 /* Delete ALL remaining messages */ 08000 nummsg = x - 1; 08001 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08002 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08003 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08004 DELETE(vms->curdir, x, vms->fn, vmu); 08005 } 08006 } 08007 ast_unlock_path(vms->curdir); 08008 #else /* defined(IMAP_STORAGE) */ 08009 if (vms->deleted) { 08010 /* Since we now expunge after each delete, deleting in reverse order 08011 * ensures that no reordering occurs between each step. */ 08012 for (x = vms->dh_arraysize - 1; x >= 0; x--) { 08013 if (vms->deleted[x]) { 08014 ast_debug(3, "IMAP delete of %d\n", x); 08015 DELETE(vms->curdir, x, vms->fn, vmu); 08016 } 08017 } 08018 } 08019 #endif 08020 08021 done: 08022 if (vms->deleted && vmu->maxmsg) { 08023 memset(vms->deleted, 0, vms->dh_arraysize * sizeof(int)); 08024 } 08025 if (vms->heard && vmu->maxmsg) { 08026 memset(vms->heard, 0, vms->dh_arraysize * sizeof(int)); 08027 } 08028 08029 return 0; 08030 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 11104 of file app_voicemail.c.
References AST_LIST_TRAVERSE, ast_strdup, ast_vm_user::context, and ast_vm_user::list.
Referenced by handle_voicemail_show_users().
11105 { 11106 int which = 0; 11107 int wordlen; 11108 struct ast_vm_user *vmu; 11109 const char *context = ""; 11110 11111 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11112 if (pos > 4) 11113 return NULL; 11114 if (pos == 3) 11115 return (state == 0) ? ast_strdup("for") : NULL; 11116 wordlen = strlen(word); 11117 AST_LIST_TRAVERSE(&users, vmu, list) { 11118 if (!strncasecmp(word, vmu->context, wordlen)) { 11119 if (context && strcmp(context, vmu->context) && ++which > state) 11120 return ast_strdup(vmu->context); 11121 /* ignore repeated contexts ? */ 11122 context = vmu->context; 11123 } 11124 } 11125 return NULL; 11126 }
static int copy | ( | char * | infile, | |
char * | outfile | |||
) | [static] |
Utility function to copy a file.
infile | The path to the file to be copied. The file must be readable, it is opened in read only mode. | |
outfile | The path for which to copy the file to. The directory permissions must allow the creation (or truncation) of the file, and allow for opening the file in write only mode. |
Definition at line 4069 of file app_voicemail.c.
References ast_log(), errno, and VOICEMAIL_FILE_MODE.
Referenced by ast_filehelper(), ast_func_read(), ast_func_read2(), ast_func_write(), handle_cli_transcoder_show(), iax2_register(), and vm_forwardoptions().
04070 { 04071 int ifd; 04072 int ofd; 04073 int res; 04074 int len; 04075 char buf[4096]; 04076 04077 #ifdef HARDLINK_WHEN_POSSIBLE 04078 /* Hard link if possible; saves disk space & is faster */ 04079 if (link(infile, outfile)) { 04080 #endif 04081 if ((ifd = open(infile, O_RDONLY)) < 0) { 04082 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04083 return -1; 04084 } 04085 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04086 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04087 close(ifd); 04088 return -1; 04089 } 04090 do { 04091 len = read(ifd, buf, sizeof(buf)); 04092 if (len < 0) { 04093 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04094 close(ifd); 04095 close(ofd); 04096 unlink(outfile); 04097 } 04098 if (len) { 04099 res = write(ofd, buf, len); 04100 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04101 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04102 close(ifd); 04103 close(ofd); 04104 unlink(outfile); 04105 } 04106 } 04107 } while (len); 04108 close(ifd); 04109 close(ofd); 04110 return 0; 04111 #ifdef HARDLINK_WHEN_POSSIBLE 04112 } else { 04113 /* Hard link succeeded */ 04114 return 0; 04115 } 04116 #endif 04117 }
static int copy_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
int | imbox, | |||
int | msgnum, | |||
long | duration, | |||
struct ast_vm_user * | recip, | |||
char * | fmt, | |||
char * | dir, | |||
const char * | flag | |||
) | [static] |
Copies a message from one mailbox to another.
chan | ||
vmu | ||
imbox | ||
msgnum | ||
duration | ||
recip | ||
fmt | ||
dir | ||
flag | This is only used by file storage based mailboxes. |
Definition at line 5306 of file app_voicemail.c.
References ast_copy_string(), ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, ast_strlen_zero(), ast_unlock_path(), ast_channel::caller, ast_vm_user::context, COPY, copy_plain_file(), create_dirpath(), ERROR_LOCK_PATH, EXISTS, ast_party_caller::id, inprocess_count(), ast_channel::language, last_message_index(), ast_vm_user::mailbox, make_dir(), make_file(), maxmsg, mbox(), ast_party_id::name, notify_new_message(), ast_party_id::number, S_COR, STORE, ast_party_name::str, ast_party_number::str, ast_party_name::valid, ast_party_number::valid, vm_delete(), and vm_lock_path().
Referenced by forward_message().
05307 { 05308 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05309 const char *frombox = mbox(vmu, imbox); 05310 const char *userfolder; 05311 int recipmsgnum; 05312 int res = 0; 05313 05314 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05315 05316 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05317 userfolder = "Urgent"; 05318 } else { 05319 userfolder = "INBOX"; 05320 } 05321 05322 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05323 05324 if (!dir) 05325 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05326 else 05327 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05328 05329 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05330 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05331 05332 if (vm_lock_path(todir)) 05333 return ERROR_LOCK_PATH; 05334 05335 recipmsgnum = last_message_index(recip, todir) + 1; 05336 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05337 make_file(topath, sizeof(topath), todir, recipmsgnum); 05338 #ifndef ODBC_STORAGE 05339 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05340 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05341 } else { 05342 #endif 05343 /* If we are prepending a message for ODBC, then the message already 05344 * exists in the database, but we want to force copying from the 05345 * filesystem (since only the FS contains the prepend). */ 05346 copy_plain_file(frompath, topath); 05347 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05348 vm_delete(topath); 05349 #ifndef ODBC_STORAGE 05350 } 05351 #endif 05352 } else { 05353 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05354 res = -1; 05355 } 05356 ast_unlock_path(todir); 05357 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05358 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05359 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05360 flag); 05361 05362 return res; 05363 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Definition at line 4128 of file app_voicemail.c.
References ast_check_realtime(), ast_filecopy(), ast_load_realtime(), exten, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
Referenced by copy_message().
04129 { 04130 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04131 struct ast_variable *tmp,*var = NULL; 04132 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04133 ast_filecopy(frompath, topath, NULL); 04134 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04135 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04136 if (ast_check_realtime("voicemail_data")) { 04137 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04138 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04139 for (tmp = var; tmp; tmp = tmp->next) { 04140 if (!strcasecmp(tmp->name, "origmailbox")) { 04141 origmailbox = tmp->value; 04142 } else if (!strcasecmp(tmp->name, "context")) { 04143 context = tmp->value; 04144 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04145 macrocontext = tmp->value; 04146 } else if (!strcasecmp(tmp->name, "exten")) { 04147 exten = tmp->value; 04148 } else if (!strcasecmp(tmp->name, "priority")) { 04149 priority = tmp->value; 04150 } else if (!strcasecmp(tmp->name, "callerchan")) { 04151 callerchan = tmp->value; 04152 } else if (!strcasecmp(tmp->name, "callerid")) { 04153 callerid = tmp->value; 04154 } else if (!strcasecmp(tmp->name, "origdate")) { 04155 origdate = tmp->value; 04156 } else if (!strcasecmp(tmp->name, "origtime")) { 04157 origtime = tmp->value; 04158 } else if (!strcasecmp(tmp->name, "category")) { 04159 category = tmp->value; 04160 } else if (!strcasecmp(tmp->name, "duration")) { 04161 duration = tmp->value; 04162 } 04163 } 04164 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); 04165 } 04166 copy(frompath2, topath2); 04167 ast_variables_destroy(var); 04168 }
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 3964 of file app_voicemail.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
Referenced by manager_list_voicemail_users(), and open_mailbox().
03965 { 03966 03967 int vmcount = 0; 03968 DIR *vmdir = NULL; 03969 struct dirent *vment = NULL; 03970 03971 if (vm_lock_path(dir)) 03972 return ERROR_LOCK_PATH; 03973 03974 if ((vmdir = opendir(dir))) { 03975 while ((vment = readdir(vmdir))) { 03976 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03977 vmcount++; 03978 } 03979 } 03980 closedir(vmdir); 03981 } 03982 ast_unlock_path(dir); 03983 03984 return vmcount; 03985 }
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 1681 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
01682 { 01683 mode_t mode = VOICEMAIL_DIR_MODE; 01684 int res; 01685 01686 make_dir(dest, len, context, ext, folder); 01687 if ((res = ast_mkdir(dest, mode))) { 01688 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01689 return -1; 01690 } 01691 return 0; 01692 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 13110 of file app_voicemail.c.
References ast_copy_string(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_suite_event_notify, ast_verb, ast_verbose, ast_waitfordigit(), ast_channel::context, ast_channel::exten, option_verbose, ast_channel::priority, and VERBOSE_PREFIX_3.
Referenced by advanced_options(), and vm_execmain().
13111 { 13112 int cmd = 0; 13113 char destination[80] = ""; 13114 int retries = 0; 13115 13116 if (!num) { 13117 ast_verb(3, "Destination number will be entered manually\n"); 13118 while (retries < 3 && cmd != 't') { 13119 destination[1] = '\0'; 13120 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13121 if (!cmd) 13122 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13123 if (!cmd) 13124 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13125 if (!cmd) { 13126 cmd = ast_waitfordigit(chan, 6000); 13127 if (cmd) 13128 destination[0] = cmd; 13129 } 13130 if (!cmd) { 13131 retries++; 13132 } else { 13133 13134 if (cmd < 0) 13135 return 0; 13136 if (cmd == '*') { 13137 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13138 return 0; 13139 } 13140 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13141 retries++; 13142 else 13143 cmd = 't'; 13144 } 13145 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13146 } 13147 if (retries >= 3) { 13148 return 0; 13149 } 13150 13151 } else { 13152 if (option_verbose > 2) 13153 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13154 ast_copy_string(destination, num, sizeof(destination)); 13155 } 13156 13157 if (!ast_strlen_zero(destination)) { 13158 if (destination[strlen(destination) -1 ] == '*') 13159 return 0; 13160 if (option_verbose > 2) 13161 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13162 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13163 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13164 chan->priority = 0; 13165 return 9; 13166 } 13167 return 0; 13168 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static] |
Definition at line 10687 of file app_voicemail.c.
References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_strlen_zero(), ast_test_flag, ast_vm_user::context, globalflags, ast_vm_user::list, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
Referenced by actual_load_config(), and append_mailbox().
10688 { 10689 struct ast_vm_user *vmu; 10690 10691 if (!ast_strlen_zero(box) && box[0] == '*') { 10692 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10693 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10694 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10695 "\n\tand will be ignored.\n", box, context); 10696 return NULL; 10697 } 10698 10699 AST_LIST_TRAVERSE(&users, vmu, list) { 10700 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10701 if (strcasecmp(vmu->context, context)) { 10702 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10703 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10704 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10705 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10706 } 10707 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10708 return NULL; 10709 } 10710 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10711 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10712 return NULL; 10713 } 10714 } 10715 10716 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10717 return NULL; 10718 10719 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10720 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10721 10722 AST_LIST_INSERT_TAIL(&users, vmu, list); 10723 10724 return vmu; 10725 }
static struct ast_vm_user* find_user | ( | struct ast_vm_user * | ivm, | |
const char * | context, | |||
const char * | mailbox | |||
) | [static] |
Finds a voicemail user from the users file or the realtime engine.
ivm | ||
context | ||
mailbox |
Definition at line 1433 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_malloc, ast_set2_flag, ast_strdup, ast_test_flag, find_user_realtime(), globalflags, ast_vm_user::list, VM_ALLOCED, and VM_SEARCH.
01434 { 01435 /* This function could be made to generate one from a database, too */ 01436 struct ast_vm_user *vmu = NULL, *cur; 01437 AST_LIST_LOCK(&users); 01438 01439 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01440 context = "default"; 01441 01442 AST_LIST_TRAVERSE(&users, cur, list) { 01443 #ifdef IMAP_STORAGE 01444 if (cur->imapversion != imapversion) { 01445 continue; 01446 } 01447 #endif 01448 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01449 break; 01450 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01451 break; 01452 } 01453 if (cur) { 01454 /* Make a copy, so that on a reload, we have no race */ 01455 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01456 *vmu = *cur; 01457 if (!ivm) { 01458 vmu->emailbody = ast_strdup(cur->emailbody); 01459 vmu->emailsubject = ast_strdup(cur->emailsubject); 01460 } 01461 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01462 AST_LIST_NEXT(vmu, list) = NULL; 01463 } 01464 } else 01465 vmu = find_user_realtime(ivm, context, mailbox); 01466 AST_LIST_UNLOCK(&users); 01467 return vmu; 01468 }
static struct ast_vm_user* find_user_realtime | ( | struct ast_vm_user * | ivm, | |
const char * | context, | |||
const char * | mailbox | |||
) | [static] |
Finds a voicemail user from the realtime engine.
ivm | ||
context | ||
mailbox | This is called as a fall through case when the normal find_user() was not able to find a user. That is, the default it so look in the usual voicemail users file first. |
Definition at line 1396 of file app_voicemail.c.
References apply_options_full(), ast_calloc, ast_copy_string(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), free_user(), globalflags, populate_defaults(), SENTINEL, var, VM_ALLOCED, and VM_SEARCH.
01397 { 01398 struct ast_variable *var; 01399 struct ast_vm_user *retval; 01400 01401 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01402 if (!ivm) 01403 ast_set_flag(retval, VM_ALLOCED); 01404 else 01405 memset(retval, 0, sizeof(*retval)); 01406 if (mailbox) 01407 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01408 populate_defaults(retval); 01409 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) 01410 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01411 else 01412 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01413 if (var) { 01414 apply_options_full(retval, var); 01415 ast_variables_destroy(var); 01416 } else { 01417 if (!ivm) 01418 free_user(retval); 01419 retval = NULL; 01420 } 01421 } 01422 return retval; 01423 }
static int forward_message | ( | struct ast_channel * | chan, | |
char * | context, | |||
struct vm_state * | vms, | |||
struct ast_vm_user * | sender, | |||
char * | fmt, | |||
int | is_new_message, | |||
signed char | record_gain, | |||
int | urgent | |||
) | [static] |
Sends a voicemail message to a mailbox recipient.
chan | ||
context | ||
vms | ||
sender | ||
fmt | ||
is_new_message | Used to indicate the mode for which this method was invoked. Will be 0 when called to forward an existing message (option 8) Will be 1 when called to leave a message (option 3->5) | |
record_gain | ||
urgent | Reads the destination mailbox(es) from keypad input for CID, or if use_directory feature is enabled, the Directory. |
When in the forward message mode (is_new_message == 0):
Definition at line 7135 of file app_voicemail.c.
References ast_clear_flag, ast_copy_string(), ast_fileexists(), ast_filerename(), AST_LIST_EMPTY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_LOG_ERROR, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_say_digit_str(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_waitfordigit(), ast_channel::caller, ast_vm_user::context, ast_channel::context, copy_message(), vm_state::curbox, vm_state::curdir, vm_state::curmsg, DISPOSE, ast_channel::exten, find_user(), free_user(), globalflags, ast_party_caller::id, inboxcount(), inprocess_count(), ast_channel::language, leave_voicemail(), ast_app::list, LOG_ERROR, LOG_NOTICE, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_party_id::name, ast_party_id::number, pbx_exec(), pbx_findapp(), ast_channel::priority, RETRIEVE, run_externnotify(), S_COR, S_OR, sendmail(), serveremail, STORE, ast_party_name::str, ast_party_number::str, strsep(), vm_state::username, ast_party_name::valid, ast_party_number::valid, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), VM_FWDURGAUTO, VM_SPOOL_DIR, and vmfmts.
Referenced by vm_execmain().
07136 { 07137 #ifdef IMAP_STORAGE 07138 int todircount = 0; 07139 struct vm_state *dstvms; 07140 #endif 07141 char username[70]=""; 07142 char fn[PATH_MAX]; /* for playback of name greeting */ 07143 char ecodes[16] = "#"; 07144 int res = 0, cmd = 0; 07145 struct ast_vm_user *receiver = NULL, *vmtmp; 07146 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07147 char *stringp; 07148 const char *s; 07149 int saved_messages = 0; 07150 int valid_extensions = 0; 07151 char *dir; 07152 int curmsg; 07153 char urgent_str[7] = ""; 07154 int prompt_played = 0; 07155 #ifndef IMAP_STORAGE 07156 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07157 #endif 07158 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07159 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07160 } 07161 07162 if (vms == NULL) return -1; 07163 dir = vms->curdir; 07164 curmsg = vms->curmsg; 07165 07166 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07167 while (!res && !valid_extensions) { 07168 int use_directory = 0; 07169 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07170 int done = 0; 07171 int retries = 0; 07172 cmd = 0; 07173 while ((cmd >= 0) && !done ){ 07174 if (cmd) 07175 retries = 0; 07176 switch (cmd) { 07177 case '1': 07178 use_directory = 0; 07179 done = 1; 07180 break; 07181 case '2': 07182 use_directory = 1; 07183 done = 1; 07184 break; 07185 case '*': 07186 cmd = 't'; 07187 done = 1; 07188 break; 07189 default: 07190 /* Press 1 to enter an extension press 2 to use the directory */ 07191 cmd = ast_play_and_wait(chan, "vm-forward"); 07192 if (!cmd) { 07193 cmd = ast_waitfordigit(chan, 3000); 07194 } 07195 if (!cmd) { 07196 retries++; 07197 } 07198 if (retries > 3) { 07199 cmd = 't'; 07200 done = 1; 07201 } 07202 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07203 } 07204 } 07205 if (cmd < 0 || cmd == 't') 07206 break; 07207 } 07208 07209 if (use_directory) { 07210 /* use app_directory */ 07211 07212 char old_context[sizeof(chan->context)]; 07213 char old_exten[sizeof(chan->exten)]; 07214 int old_priority; 07215 struct ast_app* directory_app; 07216 07217 directory_app = pbx_findapp("Directory"); 07218 if (directory_app) { 07219 char vmcontext[256]; 07220 /* make backup copies */ 07221 memcpy(old_context, chan->context, sizeof(chan->context)); 07222 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07223 old_priority = chan->priority; 07224 07225 /* call the the Directory, changes the channel */ 07226 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07227 res = pbx_exec(chan, directory_app, vmcontext); 07228 07229 ast_copy_string(username, chan->exten, sizeof(username)); 07230 07231 /* restore the old context, exten, and priority */ 07232 memcpy(chan->context, old_context, sizeof(chan->context)); 07233 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07234 chan->priority = old_priority; 07235 } else { 07236 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07237 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07238 } 07239 } else { 07240 /* Ask for an extension */ 07241 ast_test_suite_event_notify("PLAYBACK", "Message: vm-extension"); 07242 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07243 prompt_played++; 07244 if (res || prompt_played > 4) 07245 break; 07246 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07247 break; 07248 } 07249 07250 /* start all over if no username */ 07251 if (ast_strlen_zero(username)) 07252 continue; 07253 stringp = username; 07254 s = strsep(&stringp, "*"); 07255 /* start optimistic */ 07256 valid_extensions = 1; 07257 while (s) { 07258 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07259 int oldmsgs; 07260 int newmsgs; 07261 int capacity; 07262 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07263 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07264 /* Shouldn't happen, but allow trying another extension if it does */ 07265 res = ast_play_and_wait(chan, "pbx-invalid"); 07266 valid_extensions = 0; 07267 break; 07268 } 07269 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07270 if ((newmsgs + oldmsgs) >= capacity) { 07271 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07272 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07273 valid_extensions = 0; 07274 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07275 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07276 free_user(vmtmp); 07277 } 07278 inprocess_count(receiver->mailbox, receiver->context, -1); 07279 break; 07280 } 07281 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07282 } else { 07283 /* XXX Optimization for the future. When we encounter a single bad extension, 07284 * bailing out on all of the extensions may not be the way to go. We should 07285 * probably just bail on that single extension, then allow the user to enter 07286 * several more. XXX 07287 */ 07288 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07289 free_user(receiver); 07290 } 07291 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07292 /* "I am sorry, that's not a valid extension. Please try again." */ 07293 res = ast_play_and_wait(chan, "pbx-invalid"); 07294 valid_extensions = 0; 07295 break; 07296 } 07297 07298 /* play name if available, else play extension number */ 07299 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07300 RETRIEVE(fn, -1, s, receiver->context); 07301 if (ast_fileexists(fn, NULL, NULL) > 0) { 07302 res = ast_stream_and_wait(chan, fn, ecodes); 07303 if (res) { 07304 DISPOSE(fn, -1); 07305 return res; 07306 } 07307 } else { 07308 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07309 } 07310 DISPOSE(fn, -1); 07311 07312 s = strsep(&stringp, "*"); 07313 } 07314 /* break from the loop of reading the extensions */ 07315 if (valid_extensions) 07316 break; 07317 } 07318 /* check if we're clear to proceed */ 07319 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07320 return res; 07321 if (is_new_message == 1) { 07322 struct leave_vm_options leave_options; 07323 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07324 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07325 07326 /* Send VoiceMail */ 07327 memset(&leave_options, 0, sizeof(leave_options)); 07328 leave_options.record_gain = record_gain; 07329 cmd = leave_voicemail(chan, mailbox, &leave_options); 07330 } else { 07331 /* Forward VoiceMail */ 07332 long duration = 0; 07333 struct vm_state vmstmp; 07334 int copy_msg_result = 0; 07335 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07336 07337 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07338 07339 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07340 if (!cmd) { 07341 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07342 #ifdef IMAP_STORAGE 07343 int attach_user_voicemail; 07344 char *myserveremail = serveremail; 07345 07346 /* get destination mailbox */ 07347 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07348 if (!dstvms) { 07349 dstvms = create_vm_state_from_user(vmtmp); 07350 } 07351 if (dstvms) { 07352 init_mailstream(dstvms, 0); 07353 if (!dstvms->mailstream) { 07354 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07355 } else { 07356 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07357 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07358 } 07359 } else { 07360 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07361 } 07362 if (!ast_strlen_zero(vmtmp->serveremail)) 07363 myserveremail = vmtmp->serveremail; 07364 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07365 /* NULL category for IMAP storage */ 07366 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07367 dstvms->curbox, 07368 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07369 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07370 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07371 NULL, urgent_str); 07372 #else 07373 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07374 #endif 07375 saved_messages++; 07376 AST_LIST_REMOVE_CURRENT(list); 07377 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07378 free_user(vmtmp); 07379 if (res) 07380 break; 07381 } 07382 AST_LIST_TRAVERSE_SAFE_END; 07383 if (saved_messages > 0 && !copy_msg_result) { 07384 /* give confirmation that the message was saved */ 07385 /* commented out since we can't forward batches yet 07386 if (saved_messages == 1) 07387 res = ast_play_and_wait(chan, "vm-message"); 07388 else 07389 res = ast_play_and_wait(chan, "vm-messages"); 07390 if (!res) 07391 res = ast_play_and_wait(chan, "vm-saved"); */ 07392 #ifdef IMAP_STORAGE 07393 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07394 if (ast_strlen_zero(vmstmp.introfn)) 07395 #endif 07396 res = ast_play_and_wait(chan, "vm-msgsaved"); 07397 } 07398 #ifndef IMAP_STORAGE 07399 else { 07400 /* with IMAP, mailbox full warning played by imap_check_limits */ 07401 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07402 } 07403 /* Restore original message without prepended message if backup exists */ 07404 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07405 strcpy(textfile, msgfile); 07406 strcpy(backup, msgfile); 07407 strcpy(backup_textfile, msgfile); 07408 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07409 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07410 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07411 if (ast_fileexists(backup, NULL, NULL) > 0) { 07412 ast_filerename(backup, msgfile, NULL); 07413 rename(backup_textfile, textfile); 07414 } 07415 #endif 07416 } 07417 DISPOSE(dir, curmsg); 07418 #ifndef IMAP_STORAGE 07419 if (cmd) { /* assuming hangup, cleanup backup file */ 07420 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07421 strcpy(textfile, msgfile); 07422 strcpy(backup_textfile, msgfile); 07423 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07424 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07425 rename(backup_textfile, textfile); 07426 } 07427 #endif 07428 } 07429 07430 /* If anything failed above, we still have this list to free */ 07431 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07432 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07433 free_user(vmtmp); 07434 } 07435 return res ? res : cmd; 07436 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1736 of file app_voicemail.c.
References ast_free, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, and VM_ALLOCED.
01737 { 01738 if (ast_test_flag(vmu, VM_ALLOCED)) { 01739 01740 ast_free(vmu->emailbody); 01741 vmu->emailbody = NULL; 01742 01743 ast_free(vmu->emailsubject); 01744 vmu->emailsubject = NULL; 01745 01746 ast_free(vmu); 01747 } 01748 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11703 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_set_flag, free_user(), ast_vm_user::list, and VM_ALLOCED.
Referenced by actual_load_config(), and unload_module().
11704 { 11705 struct ast_vm_user *current; 11706 AST_LIST_LOCK(&users); 11707 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11708 ast_set_flag(current, VM_ALLOCED); 11709 free_user(current); 11710 } 11711 AST_LIST_UNLOCK(&users); 11712 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11715 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free_zone(), and vm_zone::list.
Referenced by actual_load_config(), and unload_module().
11716 { 11717 struct vm_zone *zcur; 11718 AST_LIST_LOCK(&zones); 11719 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11720 free_zone(zcur); 11721 AST_LIST_UNLOCK(&zones); 11722 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5074 of file app_voicemail.c.
References ast_free.
05075 { 05076 ast_free(z); 05077 }
static int get_date | ( | char * | s, | |
int | len | |||
) | [static] |
Gets the current date and time, as formatted string.
s | The buffer to hold the output formatted date. | |
len | the length of the buffer. Used to prevent buffer overflow in ast_strftime. |
Definition at line 5030 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
05031 { 05032 struct ast_tm tm; 05033 struct timeval t = ast_tvnow(); 05034 05035 ast_localtime(&t, &tm, "UTC"); 05036 05037 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05038 }
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 6747 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_fileexists(), ast_play_and_wait(), ast_say_number(), ast_test_suite_event_notify, ast_verb, ast_waitfordigit(), ast_channel::language, mbox(), and vm_play_folder_name().
Referenced by get_folder2().
06748 { 06749 int x; 06750 int d; 06751 char fn[PATH_MAX]; 06752 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06753 if (d) 06754 return d; 06755 for (x = start; x < 5; x++) { /* For all folders */ 06756 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06757 return d; 06758 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06759 if (d) 06760 return d; 06761 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06762 06763 /* The inbox folder can have its name changed under certain conditions 06764 * so this checks if the sound file exists for the inbox folder name and 06765 * if it doesn't, plays the default name instead. */ 06766 if (x == 0) { 06767 if (ast_fileexists(fn, NULL, NULL)) { 06768 d = vm_play_folder_name(chan, fn); 06769 } else { 06770 ast_verb(1, "failed to find %s\n", fn); 06771 d = vm_play_folder_name(chan, "vm-INBOX"); 06772 } 06773 } else { 06774 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06775 d = vm_play_folder_name(chan, fn); 06776 } 06777 06778 if (d) 06779 return d; 06780 d = ast_waitfordigit(chan, 500); 06781 if (d) 06782 return d; 06783 } 06784 06785 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06786 if (d) 06787 return d; 06788 d = ast_waitfordigit(chan, 4000); 06789 return d; 06790 }
static int get_folder2 | ( | struct ast_channel * | chan, | |
char * | fn, | |||
int | start | |||
) | [static] |
plays a prompt and waits for a keypress.
chan | ||
fn | the name of the voice prompt file to be played. For example, 'vm-changeto', 'vm-savefolder' | |
start | Does not appear to be used at this time. |
Definition at line 6804 of file app_voicemail.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
Referenced by vm_execmain().
06805 { 06806 int res = 0; 06807 int loops = 0; 06808 06809 res = ast_play_and_wait(chan, fn); /* Folder name */ 06810 while (((res < '0') || (res > '9')) && 06811 (res != '#') && (res >= 0) && 06812 loops < 4) { 06813 res = get_folder(chan, 0); 06814 loops++; 06815 } 06816 if (loops == 4) { /* give up */ 06817 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06818 return '#'; 06819 } 06820 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06821 return res; 06822 }
static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1723 of file app_voicemail.c.
References ARRAY_LEN.
Referenced by vm_execmain().
01724 { 01725 size_t i; 01726 01727 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01728 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01729 return i; 01730 } 01731 } 01732 01733 return -1; 01734 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11486 of file app_voicemail.c.
References ast_calloc, ast_free, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), mwi_sub_task::context, mwi_sub_task::mailbox, mwi_sub, poll_subscribed_mailbox(), mwi_sub_task::uniqueid, and ast_event_sub::uniqueid.
Referenced by mwi_sub_event_cb().
11487 { 11488 unsigned int len; 11489 struct mwi_sub *mwi_sub; 11490 struct mwi_sub_task *p = datap; 11491 11492 len = sizeof(*mwi_sub); 11493 if (!ast_strlen_zero(p->mailbox)) 11494 len += strlen(p->mailbox); 11495 11496 if (!ast_strlen_zero(p->context)) 11497 len += strlen(p->context) + 1; /* Allow for seperator */ 11498 11499 if (!(mwi_sub = ast_calloc(1, len))) 11500 return -1; 11501 11502 mwi_sub->uniqueid = p->uniqueid; 11503 if (!ast_strlen_zero(p->mailbox)) 11504 strcpy(mwi_sub->mailbox, p->mailbox); 11505 11506 if (!ast_strlen_zero(p->context)) { 11507 strcat(mwi_sub->mailbox, "@"); 11508 strcat(mwi_sub->mailbox, p->context); 11509 } 11510 11511 AST_RWLIST_WRLOCK(&mwi_subs); 11512 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11513 AST_RWLIST_UNLOCK(&mwi_subs); 11514 ast_free((void *) p->mailbox); 11515 ast_free((void *) p->context); 11516 ast_free(p); 11517 poll_subscribed_mailbox(mwi_sub); 11518 return 0; 11519 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11464 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, mwi_sub_destroy(), ast_event_sub::uniqueid, and mwi_sub::uniqueid.
Referenced by mwi_unsub_event_cb().
11465 { 11466 struct mwi_sub *mwi_sub; 11467 uint32_t *uniqueid = datap; 11468 11469 AST_RWLIST_WRLOCK(&mwi_subs); 11470 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11471 if (mwi_sub->uniqueid == *uniqueid) { 11472 AST_LIST_REMOVE_CURRENT(entry); 11473 break; 11474 } 11475 } 11476 AST_RWLIST_TRAVERSE_SAFE_END 11477 AST_RWLIST_UNLOCK(&mwi_subs); 11478 11479 if (mwi_sub) 11480 mwi_sub_destroy(mwi_sub); 11481 11482 ast_free(uniqueid); 11483 return 0; 11484 }
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 11239 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.
11240 { 11241 switch (cmd) { 11242 case CLI_INIT: 11243 e->command = "voicemail reload"; 11244 e->usage = 11245 "Usage: voicemail reload\n" 11246 " Reload voicemail configuration\n"; 11247 return NULL; 11248 case CLI_GENERATE: 11249 return NULL; 11250 } 11251 11252 if (a->argc != 2) 11253 return CLI_SHOWUSAGE; 11254 11255 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11256 load_config(1); 11257 11258 return CLI_SUCCESS; 11259 }
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 11129 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::list, 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.
11130 { 11131 struct ast_vm_user *vmu; 11132 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11133 const char *context = NULL; 11134 int users_counter = 0; 11135 11136 switch (cmd) { 11137 case CLI_INIT: 11138 e->command = "voicemail show users"; 11139 e->usage = 11140 "Usage: voicemail show users [for <context>]\n" 11141 " Lists all mailboxes currently set up\n"; 11142 return NULL; 11143 case CLI_GENERATE: 11144 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11145 } 11146 11147 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11148 return CLI_SHOWUSAGE; 11149 if (a->argc == 5) { 11150 if (strcmp(a->argv[3],"for")) 11151 return CLI_SHOWUSAGE; 11152 context = a->argv[4]; 11153 } 11154 11155 if (ast_check_realtime("voicemail")) { 11156 if (!context) { 11157 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11158 return CLI_SHOWUSAGE; 11159 } 11160 return show_users_realtime(a->fd, context); 11161 } 11162 11163 AST_LIST_LOCK(&users); 11164 if (AST_LIST_EMPTY(&users)) { 11165 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11166 AST_LIST_UNLOCK(&users); 11167 return CLI_FAILURE; 11168 } 11169 if (a->argc == 3) 11170 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11171 else { 11172 int count = 0; 11173 AST_LIST_TRAVERSE(&users, vmu, list) { 11174 if (!strcmp(context, vmu->context)) 11175 count++; 11176 } 11177 if (count) { 11178 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11179 } else { 11180 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11181 AST_LIST_UNLOCK(&users); 11182 return CLI_FAILURE; 11183 } 11184 } 11185 AST_LIST_TRAVERSE(&users, vmu, list) { 11186 int newmsgs = 0, oldmsgs = 0; 11187 char count[12], tmp[256] = ""; 11188 11189 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 11190 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11191 inboxcount(tmp, &newmsgs, &oldmsgs); 11192 snprintf(count, sizeof(count), "%d", newmsgs); 11193 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11194 users_counter++; 11195 } 11196 } 11197 AST_LIST_UNLOCK(&users); 11198 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11199 return CLI_SUCCESS; 11200 }
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 11203 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::list, vm_zone::msg_format, vm_zone::name, vm_zone::timezone, and ast_cli_entry::usage.
11204 { 11205 struct vm_zone *zone; 11206 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11207 char *res = CLI_SUCCESS; 11208 11209 switch (cmd) { 11210 case CLI_INIT: 11211 e->command = "voicemail show zones"; 11212 e->usage = 11213 "Usage: voicemail show zones\n" 11214 " Lists zone message formats\n"; 11215 return NULL; 11216 case CLI_GENERATE: 11217 return NULL; 11218 } 11219 11220 if (a->argc != 3) 11221 return CLI_SHOWUSAGE; 11222 11223 AST_LIST_LOCK(&zones); 11224 if (!AST_LIST_EMPTY(&zones)) { 11225 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11226 AST_LIST_TRAVERSE(&zones, zone, list) { 11227 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11228 } 11229 } else { 11230 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11231 res = CLI_FAILURE; 11232 } 11233 AST_LIST_UNLOCK(&zones); 11234 11235 return res; 11236 }
static int has_voicemail | ( | const char * | mailbox, | |
const char * | folder | |||
) | [static] |
Determines if the given folder has messages.
mailbox | The @ delimited string for user. If no context is found, uses 'default' for the context. | |
folder | the folder to look in |
Definition at line 5418 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
Referenced by dahdi_handle_event(), do_monitor(), handle_hd_hf(), handle_init_event(), handle_request(), load_module(), mgcp_hangup(), mgcp_request(), mwi_send_init(), my_has_voicemail(), and vm_execmain().
05419 { 05420 char tmp[256], *tmp2 = tmp, *box, *context; 05421 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05422 if (ast_strlen_zero(folder)) { 05423 folder = "INBOX"; 05424 } 05425 while ((box = strsep(&tmp2, ",&"))) { 05426 if ((context = strchr(box, '@'))) 05427 *context++ = '\0'; 05428 else 05429 context = "default"; 05430 if (__has_voicemail(context, box, folder, 1)) 05431 return 1; 05432 /* If we are checking INBOX, we should check Urgent as well */ 05433 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05434 return 1; 05435 } 05436 } 05437 return 0; 05438 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5500 of file app_voicemail.c.
References inboxcount2().
Referenced by forward_message(), handle_voicemail_show_users(), load_module(), and manager_list_voicemail_users().
05501 { 05502 int urgentmsgs = 0; 05503 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05504 if (newmsgs) { 05505 *newmsgs += urgentmsgs; 05506 } 05507 return res; 05508 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5441 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
Referenced by append_mailbox(), inboxcount(), inboxcount2(), load_module(), poll_subscribed_mailbox(), run_externnotify(), and vm_users_data_provider_get_helper().
05442 { 05443 char tmp[256]; 05444 char *context; 05445 05446 /* If no mailbox, return immediately */ 05447 if (ast_strlen_zero(mailbox)) 05448 return 0; 05449 05450 if (newmsgs) 05451 *newmsgs = 0; 05452 if (oldmsgs) 05453 *oldmsgs = 0; 05454 if (urgentmsgs) 05455 *urgentmsgs = 0; 05456 05457 if (strchr(mailbox, ',')) { 05458 int tmpnew, tmpold, tmpurgent; 05459 char *mb, *cur; 05460 05461 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05462 mb = tmp; 05463 while ((cur = strsep(&mb, ", "))) { 05464 if (!ast_strlen_zero(cur)) { 05465 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05466 return -1; 05467 else { 05468 if (newmsgs) 05469 *newmsgs += tmpnew; 05470 if (oldmsgs) 05471 *oldmsgs += tmpold; 05472 if (urgentmsgs) 05473 *urgentmsgs += tmpurgent; 05474 } 05475 } 05476 } 05477 return 0; 05478 } 05479 05480 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05481 05482 if ((context = strchr(tmp, '@'))) 05483 *context++ = '\0'; 05484 else 05485 context = "default"; 05486 05487 if (newmsgs) 05488 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05489 if (oldmsgs) 05490 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05491 if (urgentmsgs) 05492 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05493 05494 return 0; 05495 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4200 of file app_voicemail.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by ast_eivr_getvariable(), ast_eivr_setvariable(), inchar(), sip_addheader(), and sip_removeheader().
04201 { 04202 int l; 04203 04204 if (bio->ateof) 04205 return 0; 04206 04207 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04208 if (ferror(fi)) 04209 return -1; 04210 04211 bio->ateof = 1; 04212 return 0; 04213 } 04214 04215 bio->iolen = l; 04216 bio->iocp = 0; 04217 04218 return 1; 04219 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4224 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
04225 { 04226 if (bio->iocp>=bio->iolen) { 04227 if (!inbuf(bio, fi)) 04228 return EOF; 04229 } 04230 04231 return bio->iobuf[bio->iocp++]; 04232 }
static int inprocess_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 935 of file app_voicemail.c.
References CMP_MATCH, inprocess::context, and inprocess::mailbox.
Referenced by load_module().
00936 { 00937 struct inprocess *i = obj, *j = arg; 00938 if (strcmp(i->mailbox, j->mailbox)) { 00939 return 0; 00940 } 00941 return !strcmp(i->context, j->context) ? CMP_MATCH : 0; 00942 }
static int inprocess_count | ( | const char * | context, | |
const char * | mailbox, | |||
int | delta | |||
) | [static] |
Definition at line 944 of file app_voicemail.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_atomic_fetchadd_int(), ast_log(), inprocess::count, inprocess_container, and LOG_WARNING.
Referenced by copy_message(), and forward_message().
00945 { 00946 struct inprocess *i, *arg = alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 00947 arg->context = arg->mailbox + strlen(mailbox) + 1; 00948 strcpy(arg->mailbox, mailbox); /* SAFE */ 00949 strcpy(arg->context, context); /* SAFE */ 00950 ao2_lock(inprocess_container); 00951 if ((i = ao2_find(inprocess_container, arg, 0))) { 00952 int ret = ast_atomic_fetchadd_int(&i->count, delta); 00953 ao2_unlock(inprocess_container); 00954 ao2_ref(i, -1); 00955 return ret; 00956 } 00957 if (delta < 0) { 00958 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 00959 } 00960 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 00961 ao2_unlock(inprocess_container); 00962 return 0; 00963 } 00964 i->context = i->mailbox + strlen(mailbox) + 1; 00965 strcpy(i->mailbox, mailbox); /* SAFE */ 00966 strcpy(i->context, context); /* SAFE */ 00967 i->count = delta; 00968 ao2_link(inprocess_container, i); 00969 ao2_unlock(inprocess_container); 00970 ao2_ref(i, -1); 00971 return 0; 00972 }
static int inprocess_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 929 of file app_voicemail.c.
References inprocess::mailbox.
Referenced by load_module().
static int invent_message | ( | struct ast_channel * | chan, | |
char * | context, | |||
char * | ext, | |||
int | busy, | |||
char * | ecodes | |||
) | [static] |
Definition at line 5040 of file app_voicemail.c.
References ast_fileexists(), ast_log(), ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, ast_channel::language, RETRIEVE, and VM_SPOOL_DIR.
05041 { 05042 int res; 05043 char fn[PATH_MAX]; 05044 char dest[PATH_MAX]; 05045 05046 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05047 05048 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05049 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05050 return -1; 05051 } 05052 05053 RETRIEVE(fn, -1, ext, context); 05054 if (ast_fileexists(fn, NULL, NULL) > 0) { 05055 res = ast_stream_and_wait(chan, fn, ecodes); 05056 if (res) { 05057 DISPOSE(fn, -1); 05058 return res; 05059 } 05060 } else { 05061 /* Dispose just in case */ 05062 DISPOSE(fn, -1); 05063 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05064 if (res) 05065 return res; 05066 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 05067 if (res) 05068 return res; 05069 } 05070 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05071 return res; 05072 }
static int is_valid_dtmf | ( | const char * | key | ) | [static] |
Determines if a DTMF key entered is valid.
key | The character to be compared. expects a single character. Though is capable of handling a string, this is internally copies using ast_strdupa. |
Definition at line 1371 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by actual_load_config().
01372 { 01373 int i; 01374 char *local_key = ast_strdupa(key); 01375 01376 for (i = 0; i < strlen(key); ++i) { 01377 if (!strchr(VALID_DTMF, *local_key)) { 01378 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01379 return 0; 01380 } 01381 local_key++; 01382 } 01383 return 1; 01384 }
static int last_message_index | ( | struct ast_vm_user * | vmu, | |
char * | dir | |||
) | [static] |
Determines the highest message number in use for a given user and mailbox folder.
vmu | ||
dir | the folder the mailbox folder to look for messages. Used to construct the SQL where clause. |
Definition at line 4018 of file app_voicemail.c.
References ast_debug, map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
Referenced by close_mailbox(), copy_message(), open_mailbox(), and save_to_folder().
04019 { 04020 int x; 04021 unsigned char map[MAXMSGLIMIT] = ""; 04022 DIR *msgdir; 04023 struct dirent *msgdirent; 04024 int msgdirint; 04025 char extension[4]; 04026 int stopcount = 0; 04027 04028 /* Reading the entire directory into a file map scales better than 04029 * doing a stat repeatedly on a predicted sequence. I suspect this 04030 * is partially due to stat(2) internally doing a readdir(2) itself to 04031 * find each file. */ 04032 if (!(msgdir = opendir(dir))) { 04033 return -1; 04034 } 04035 04036 while ((msgdirent = readdir(msgdir))) { 04037 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04038 map[msgdirint] = 1; 04039 stopcount++; 04040 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04041 } 04042 } 04043 closedir(msgdir); 04044 04045 for (x = 0; x < vmu->maxmsg; x++) { 04046 if (map[x] == 1) { 04047 stopcount--; 04048 } else if (map[x] == 0 && !stopcount) { 04049 break; 04050 } 04051 } 04052 04053 return x - 1; 04054 }
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 5573 of file app_voicemail.c.
References ast_canmatch_extension(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_exists_extension(), ast_fileexists(), ast_free, ast_log(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_channel::caller, ast_channel::context, ast_vm_user::context, create_dirpath(), DISPOSE, errno, ast_vm_user::exit, find_user(), ast_party_caller::id, LOG_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, ast_party_id::number, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_UNAVAIL_GREETING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), RETRIEVE, S_COR, ast_party_number::str, ast_party_number::valid, VM_OPERATOR, VM_SPOOL_DIR, and VOICEMAIL_DIR_MODE.
05574 { 05575 #ifdef IMAP_STORAGE 05576 int newmsgs, oldmsgs; 05577 #else 05578 char urgdir[PATH_MAX]; 05579 #endif 05580 char txtfile[PATH_MAX]; 05581 char tmptxtfile[PATH_MAX]; 05582 struct vm_state *vms = NULL; 05583 char callerid[256]; 05584 FILE *txt; 05585 char date[256]; 05586 int txtdes; 05587 int res = 0; 05588 int msgnum; 05589 int duration = 0; 05590 int sound_duration = 0; 05591 int ausemacro = 0; 05592 int ousemacro = 0; 05593 int ouseexten = 0; 05594 char tmpdur[16]; 05595 char priority[16]; 05596 char origtime[16]; 05597 char dir[PATH_MAX]; 05598 char tmpdir[PATH_MAX]; 05599 char fn[PATH_MAX]; 05600 char prefile[PATH_MAX] = ""; 05601 char tempfile[PATH_MAX] = ""; 05602 char ext_context[256] = ""; 05603 char fmt[80]; 05604 char *context; 05605 char ecodes[17] = "#"; 05606 struct ast_str *tmp = ast_str_create(16); 05607 char *tmpptr; 05608 struct ast_vm_user *vmu; 05609 struct ast_vm_user svm; 05610 const char *category = NULL; 05611 const char *code; 05612 const char *alldtmf = "0123456789ABCD*#"; 05613 char flag[80]; 05614 05615 if (!tmp) { 05616 return -1; 05617 } 05618 05619 ast_str_set(&tmp, 0, "%s", ext); 05620 ext = ast_str_buffer(tmp); 05621 if ((context = strchr(ext, '@'))) { 05622 *context++ = '\0'; 05623 tmpptr = strchr(context, '&'); 05624 } else { 05625 tmpptr = strchr(ext, '&'); 05626 } 05627 05628 if (tmpptr) 05629 *tmpptr++ = '\0'; 05630 05631 ast_channel_lock(chan); 05632 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05633 category = ast_strdupa(category); 05634 } 05635 ast_channel_unlock(chan); 05636 05637 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05638 ast_copy_string(flag, "Urgent", sizeof(flag)); 05639 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05640 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05641 } else { 05642 flag[0] = '\0'; 05643 } 05644 05645 ast_debug(3, "Before find_user\n"); 05646 if (!(vmu = find_user(&svm, context, ext))) { 05647 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05648 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05649 ast_free(tmp); 05650 return res; 05651 } 05652 /* Setup pre-file if appropriate */ 05653 if (strcmp(vmu->context, "default")) 05654 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05655 else 05656 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05657 05658 /* Set the path to the prefile. Will be one of 05659 VM_SPOOL_DIRcontext/ext/busy 05660 VM_SPOOL_DIRcontext/ext/unavail 05661 Depending on the flag set in options. 05662 */ 05663 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05664 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05665 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05666 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05667 } 05668 /* Set the path to the tmpfile as 05669 VM_SPOOL_DIR/context/ext/temp 05670 and attempt to create the folder structure. 05671 */ 05672 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05673 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05674 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05675 ast_free(tmp); 05676 return -1; 05677 } 05678 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05679 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05680 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05681 05682 DISPOSE(tempfile, -1); 05683 /* It's easier just to try to make it than to check for its existence */ 05684 #ifndef IMAP_STORAGE 05685 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05686 #else 05687 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05688 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05689 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05690 } 05691 #endif 05692 05693 /* Check current or macro-calling context for special extensions */ 05694 if (ast_test_flag(vmu, VM_OPERATOR)) { 05695 if (!ast_strlen_zero(vmu->exit)) { 05696 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05697 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05698 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05699 ouseexten = 1; 05700 } 05701 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05702 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05703 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05704 ouseexten = 1; 05705 } else if (!ast_strlen_zero(chan->macrocontext) 05706 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05707 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05708 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05709 ousemacro = 1; 05710 } 05711 } 05712 05713 if (!ast_strlen_zero(vmu->exit)) { 05714 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05715 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05716 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05717 } 05718 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05719 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05720 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05721 } else if (!ast_strlen_zero(chan->macrocontext) 05722 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05723 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05724 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05725 ausemacro = 1; 05726 } 05727 05728 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05729 for (code = alldtmf; *code; code++) { 05730 char e[2] = ""; 05731 e[0] = *code; 05732 if (strchr(ecodes, e[0]) == NULL 05733 && ast_canmatch_extension(chan, chan->context, e, 1, 05734 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05735 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05736 } 05737 } 05738 } 05739 05740 /* Play the beginning intro if desired */ 05741 if (!ast_strlen_zero(prefile)) { 05742 #ifdef ODBC_STORAGE 05743 int success = 05744 #endif 05745 RETRIEVE(prefile, -1, ext, context); 05746 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05747 if (ast_streamfile(chan, prefile, chan->language) > -1) 05748 res = ast_waitstream(chan, ecodes); 05749 #ifdef ODBC_STORAGE 05750 if (success == -1) { 05751 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05752 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05753 store_file(prefile, vmu->mailbox, vmu->context, -1); 05754 } 05755 #endif 05756 } else { 05757 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05758 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05759 } 05760 DISPOSE(prefile, -1); 05761 if (res < 0) { 05762 ast_debug(1, "Hang up during prefile playback\n"); 05763 free_user(vmu); 05764 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05765 ast_free(tmp); 05766 return -1; 05767 } 05768 } 05769 if (res == '#') { 05770 /* On a '#' we skip the instructions */ 05771 ast_set_flag(options, OPT_SILENT); 05772 res = 0; 05773 } 05774 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05775 if (vmu->maxmsg == 0) { 05776 if (option_debug > 2) 05777 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05778 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05779 goto leave_vm_out; 05780 } 05781 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05782 res = ast_stream_and_wait(chan, INTRO, ecodes); 05783 if (res == '#') { 05784 ast_set_flag(options, OPT_SILENT); 05785 res = 0; 05786 } 05787 } 05788 if (res > 0) 05789 ast_stopstream(chan); 05790 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05791 other than the operator -- an automated attendant or mailbox login for example */ 05792 if (res == '*') { 05793 chan->exten[0] = 'a'; 05794 chan->exten[1] = '\0'; 05795 if (!ast_strlen_zero(vmu->exit)) { 05796 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05797 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05798 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05799 } 05800 chan->priority = 0; 05801 free_user(vmu); 05802 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05803 ast_free(tmp); 05804 return 0; 05805 } 05806 05807 /* Check for a '0' here */ 05808 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05809 transfer: 05810 if (ouseexten || ousemacro) { 05811 chan->exten[0] = 'o'; 05812 chan->exten[1] = '\0'; 05813 if (!ast_strlen_zero(vmu->exit)) { 05814 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05815 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05816 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05817 } 05818 ast_play_and_wait(chan, "transfer"); 05819 chan->priority = 0; 05820 free_user(vmu); 05821 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05822 } 05823 ast_free(tmp); 05824 return OPERATOR_EXIT; 05825 } 05826 05827 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05828 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05829 if (!ast_strlen_zero(options->exitcontext)) 05830 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05831 free_user(vmu); 05832 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05833 ast_free(tmp); 05834 return res; 05835 } 05836 05837 if (res < 0) { 05838 free_user(vmu); 05839 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05840 ast_free(tmp); 05841 return -1; 05842 } 05843 /* The meat of recording the message... All the announcements and beeps have been played*/ 05844 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05845 if (!ast_strlen_zero(fmt)) { 05846 msgnum = 0; 05847 05848 #ifdef IMAP_STORAGE 05849 /* Is ext a mailbox? */ 05850 /* must open stream for this user to get info! */ 05851 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05852 if (res < 0) { 05853 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05854 ast_free(tmp); 05855 return -1; 05856 } 05857 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05858 /* It is possible under certain circumstances that inboxcount did not 05859 * create a vm_state when it was needed. This is a catchall which will 05860 * rarely be used. 05861 */ 05862 if (!(vms = create_vm_state_from_user(vmu))) { 05863 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05864 ast_free(tmp); 05865 return -1; 05866 } 05867 } 05868 vms->newmessages++; 05869 05870 /* here is a big difference! We add one to it later */ 05871 msgnum = newmsgs + oldmsgs; 05872 ast_debug(3, "Messagecount set to %d\n", msgnum); 05873 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05874 /* set variable for compatibility */ 05875 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05876 05877 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05878 goto leave_vm_out; 05879 } 05880 #else 05881 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05882 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05883 if (!res) 05884 res = ast_waitstream(chan, ""); 05885 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05886 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05887 inprocess_count(vmu->mailbox, vmu->context, -1); 05888 goto leave_vm_out; 05889 } 05890 05891 #endif 05892 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05893 txtdes = mkstemp(tmptxtfile); 05894 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05895 if (txtdes < 0) { 05896 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05897 if (!res) 05898 res = ast_waitstream(chan, ""); 05899 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05900 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05901 inprocess_count(vmu->mailbox, vmu->context, -1); 05902 goto leave_vm_out; 05903 } 05904 05905 /* Now play the beep once we have the message number for our next message. */ 05906 if (res >= 0) { 05907 /* Unless we're *really* silent, try to send the beep */ 05908 res = ast_stream_and_wait(chan, "beep", ""); 05909 } 05910 05911 /* Store information in real-time storage */ 05912 if (ast_check_realtime("voicemail_data")) { 05913 snprintf(priority, sizeof(priority), "%d", chan->priority); 05914 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05915 get_date(date, sizeof(date)); 05916 ast_callerid_merge(callerid, sizeof(callerid), 05917 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05918 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05919 "Unknown"); 05920 ast_store_realtime("voicemail_data", 05921 "origmailbox", ext, 05922 "context", chan->context, 05923 "macrocontext", chan->macrocontext, 05924 "exten", chan->exten, 05925 "priority", priority, 05926 "callerchan", chan->name, 05927 "callerid", callerid, 05928 "origdate", date, 05929 "origtime", origtime, 05930 "category", S_OR(category, ""), 05931 "filename", tmptxtfile, 05932 SENTINEL); 05933 } 05934 05935 /* Store information */ 05936 txt = fdopen(txtdes, "w+"); 05937 if (txt) { 05938 get_date(date, sizeof(date)); 05939 ast_callerid_merge(callerid, sizeof(callerid), 05940 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05941 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05942 "Unknown"); 05943 fprintf(txt, 05944 ";\n" 05945 "; Message Information file\n" 05946 ";\n" 05947 "[message]\n" 05948 "origmailbox=%s\n" 05949 "context=%s\n" 05950 "macrocontext=%s\n" 05951 "exten=%s\n" 05952 "rdnis=%s\n" 05953 "priority=%d\n" 05954 "callerchan=%s\n" 05955 "callerid=%s\n" 05956 "origdate=%s\n" 05957 "origtime=%ld\n" 05958 "category=%s\n", 05959 ext, 05960 chan->context, 05961 chan->macrocontext, 05962 chan->exten, 05963 S_COR(chan->redirecting.from.number.valid, 05964 chan->redirecting.from.number.str, "unknown"), 05965 chan->priority, 05966 chan->name, 05967 callerid, 05968 date, (long) time(NULL), 05969 category ? category : ""); 05970 } else { 05971 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05972 inprocess_count(vmu->mailbox, vmu->context, -1); 05973 if (ast_check_realtime("voicemail_data")) { 05974 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05975 } 05976 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05977 goto leave_vm_out; 05978 } 05979 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 05980 05981 if (txt) { 05982 fprintf(txt, "flag=%s\n", flag); 05983 if (sound_duration < vmu->minsecs) { 05984 fclose(txt); 05985 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 05986 ast_filedelete(tmptxtfile, NULL); 05987 unlink(tmptxtfile); 05988 if (ast_check_realtime("voicemail_data")) { 05989 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05990 } 05991 inprocess_count(vmu->mailbox, vmu->context, -1); 05992 } else { 05993 fprintf(txt, "duration=%d\n", duration); 05994 fclose(txt); 05995 if (vm_lock_path(dir)) { 05996 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 05997 /* Delete files */ 05998 ast_filedelete(tmptxtfile, NULL); 05999 unlink(tmptxtfile); 06000 inprocess_count(vmu->mailbox, vmu->context, -1); 06001 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06002 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06003 unlink(tmptxtfile); 06004 ast_unlock_path(dir); 06005 inprocess_count(vmu->mailbox, vmu->context, -1); 06006 if (ast_check_realtime("voicemail_data")) { 06007 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06008 } 06009 } else { 06010 #ifndef IMAP_STORAGE 06011 msgnum = last_message_index(vmu, dir) + 1; 06012 #endif 06013 make_file(fn, sizeof(fn), dir, msgnum); 06014 06015 /* assign a variable with the name of the voicemail file */ 06016 #ifndef IMAP_STORAGE 06017 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06018 #else 06019 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06020 #endif 06021 06022 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06023 ast_filerename(tmptxtfile, fn, NULL); 06024 rename(tmptxtfile, txtfile); 06025 inprocess_count(vmu->mailbox, vmu->context, -1); 06026 06027 /* Properly set permissions on voicemail text descriptor file. 06028 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06029 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06030 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06031 06032 ast_unlock_path(dir); 06033 if (ast_check_realtime("voicemail_data")) { 06034 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06035 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06036 } 06037 /* We must store the file first, before copying the message, because 06038 * ODBC storage does the entire copy with SQL. 06039 */ 06040 if (ast_fileexists(fn, NULL, NULL) > 0) { 06041 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06042 } 06043 06044 /* Are there to be more recipients of this message? */ 06045 while (tmpptr) { 06046 struct ast_vm_user recipu, *recip; 06047 char *exten, *cntx; 06048 06049 exten = strsep(&tmpptr, "&"); 06050 cntx = strchr(exten, '@'); 06051 if (cntx) { 06052 *cntx = '\0'; 06053 cntx++; 06054 } 06055 if ((recip = find_user(&recipu, cntx, exten))) { 06056 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06057 free_user(recip); 06058 } 06059 } 06060 #ifndef IMAP_STORAGE 06061 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06062 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06063 char sfn[PATH_MAX]; 06064 char dfn[PATH_MAX]; 06065 int x; 06066 /* It's easier just to try to make it than to check for its existence */ 06067 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06068 x = last_message_index(vmu, urgdir) + 1; 06069 make_file(sfn, sizeof(sfn), dir, msgnum); 06070 make_file(dfn, sizeof(dfn), urgdir, x); 06071 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06072 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06073 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06074 ast_copy_string(fn, dfn, sizeof(fn)); 06075 msgnum = x; 06076 } 06077 #endif 06078 /* Notification needs to happen after the copy, though. */ 06079 if (ast_fileexists(fn, NULL, NULL)) { 06080 #ifdef IMAP_STORAGE 06081 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06082 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06083 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06084 flag); 06085 #else 06086 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06087 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06088 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06089 flag); 06090 #endif 06091 } 06092 06093 /* Disposal needs to happen after the optional move and copy */ 06094 if (ast_fileexists(fn, NULL, NULL)) { 06095 DISPOSE(dir, msgnum); 06096 } 06097 } 06098 } 06099 } else { 06100 inprocess_count(vmu->mailbox, vmu->context, -1); 06101 } 06102 if (res == '0') { 06103 goto transfer; 06104 } else if (res > 0 && res != 't') 06105 res = 0; 06106 06107 if (sound_duration < vmu->minsecs) 06108 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06109 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06110 else 06111 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06112 } else 06113 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06114 leave_vm_out: 06115 free_user(vmu); 06116 06117 #ifdef IMAP_STORAGE 06118 /* expunge message - use UID Expunge if supported on IMAP server*/ 06119 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06120 if (expungeonhangup == 1) { 06121 ast_mutex_lock(&vms->lock); 06122 #ifdef HAVE_IMAP_TK2006 06123 if (LEVELUIDPLUS (vms->mailstream)) { 06124 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06125 } else 06126 #endif 06127 mail_expunge(vms->mailstream); 06128 ast_mutex_unlock(&vms->lock); 06129 } 06130 #endif 06131 06132 ast_free(tmp); 06133 return res; 06134 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11771 of file app_voicemail.c.
References actual_load_config(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_log(), ast_unload_realtime(), CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, and VOICEMAIL_CONFIG.
11772 { 11773 struct ast_config *cfg, *ucfg; 11774 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11775 int res; 11776 11777 ast_unload_realtime("voicemail"); 11778 ast_unload_realtime("voicemail_data"); 11779 11780 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11781 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11782 return 0; 11783 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11784 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11785 ucfg = NULL; 11786 } 11787 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11788 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11789 ast_config_destroy(ucfg); 11790 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11791 return 0; 11792 } 11793 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11794 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11795 return 0; 11796 } else { 11797 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11798 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11799 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11800 ucfg = NULL; 11801 } 11802 } 11803 11804 res = actual_load_config(reload, cfg, ucfg); 11805 11806 ast_config_destroy(cfg); 11807 ast_config_destroy(ucfg); 11808 11809 return res; 11810 }
static int load_module | ( | void | ) | [static] |
Definition at line 13062 of file app_voicemail.c.
References ao2_container_alloc, app, app2, app3, app4, ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_data_register_multiple, ast_install_vm_functions(), ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, ast_realtime_require_field(), ast_register_application_xml, ast_taskprocessor_get(), AST_TEST_REGISTER, cli_voicemail, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), inboxcount2(), inprocess_cmp_fn(), inprocess_container, inprocess_hash_fn(), load_config(), mailbox_exists_acf, manager_list_voicemail_users(), messagecount(), mwi_subscription_tps, my_umask, RQ_CHAR, RQ_UINTEGER3, sayname(), sayname_app, SENTINEL, vm_box_exists(), vm_data_providers, vm_exec(), vm_execmain(), VM_SPOOL_DIR, vmauthenticate(), and vmsayname_exec().
13063 { 13064 int res; 13065 my_umask = umask(0); 13066 umask(my_umask); 13067 13068 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13069 return AST_MODULE_LOAD_DECLINE; 13070 } 13071 13072 /* compute the location of the voicemail spool directory */ 13073 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13074 13075 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13076 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13077 } 13078 13079 if ((res = load_config(0))) 13080 return res; 13081 13082 res = ast_register_application_xml(app, vm_exec); 13083 res |= ast_register_application_xml(app2, vm_execmain); 13084 res |= ast_register_application_xml(app3, vm_box_exists); 13085 res |= ast_register_application_xml(app4, vmauthenticate); 13086 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13087 res |= ast_custom_function_register(&mailbox_exists_acf); 13088 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13089 #ifdef TEST_FRAMEWORK 13090 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13091 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13092 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13093 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13094 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13095 #endif 13096 13097 if (res) 13098 return res; 13099 13100 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13101 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13102 13103 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13104 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13105 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13106 13107 return res; 13108 }
static int make_dir | ( | char * | dest, | |
int | len, | |||
const char * | context, | |||
const char * | ext, | |||
const char * | folder | |||
) | [static] |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.
dest | The variable to hold the output generated path expression. This buffer should be of size PATH_MAX. | |
len | The length of the path string that was written out. | |
context | ||
ext | ||
folder |
Definition at line 1635 of file app_voicemail.c.
References VM_SPOOL_DIR.
01636 { 01637 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01638 }
static void make_email_file | ( | FILE * | p, | |
char * | srcemail, | |||
struct ast_vm_user * | vmu, | |||
int | msgnum, | |||
char * | context, | |||
char * | mailbox, | |||
const char * | fromfolder, | |||
char * | cidnum, | |||
char * | cidname, | |||
char * | attach, | |||
char * | attach2, | |||
char * | format, | |||
int | duration, | |||
int | attach_user_voicemail, | |||
struct ast_channel * | chan, | |||
const char * | category, | |||
int | imap, | |||
const char * | flag | |||
) | [static] |
Creates the email file to be sent to indicate a new voicemail exists for a user.
p | The output file to generate the email contents into. | |
srcemail | The email address to send the email to, presumably the email address for the owner of the mailbox. | |
vmu | The voicemail user who is sending the voicemail. | |
msgnum | The message index in the mailbox folder. | |
context | ||
mailbox | The voicemail box to read the voicemail to be notified in this email. | |
fromfolder | ||
cidnum | The caller ID number. | |
cidname | The caller ID name. | |
attach | the name of the sound file to be attached to the email, if attach_user_voicemail == 1. | |
attach2 | ||
format | The message sound file format. i.e. .wav | |
duration | The time of the message content, in seconds. | |
attach_user_voicemail | if 1, the sound file is attached to the email. | |
chan | ||
category | ||
imap | if == 1, indicates the target folder for the email notification to be sent to will be an IMAP mailstore. This causes additional mailbox headers to be set, which would facilitate searching for the email in the destination IMAP folder. | |
flag | The email body, and base 64 encoded attachement (if any) are stored to the file identified by *p. This method does not actually send the email. That is done by invoking the configure 'mailcmd' and piping this generated file into it, or with the sendemail() function. |
Definition at line 4517 of file app_voicemail.c.
References add_email_attachment(), ast_channel_unref, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, ast_localtime(), ast_log(), ast_random(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strftime_locale(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), charset, check_mime(), CONFIG_FLAG_NOCACHE, config_flags, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, emailbody, emaildateformat, ast_vm_user::emailsubject, emailsubject, ENDL, fromstring, ast_vm_user::fullname, globalflags, ast_vm_user::locale, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, ast_channel::name, prep_email_sub_vars(), ast_channel::priority, S_OR, strip_control_and_high(), VM_PBXSKIP, and vmu_tm().
Referenced by sendmail().
04518 { 04519 char date[256]; 04520 char host[MAXHOSTNAMELEN] = ""; 04521 char who[256]; 04522 char bound[256]; 04523 char dur[256]; 04524 struct ast_tm tm; 04525 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04526 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04527 char *greeting_attachment; 04528 char filename[256]; 04529 04530 if (!str1 || !str2) { 04531 ast_free(str1); 04532 ast_free(str2); 04533 return; 04534 } 04535 04536 if (cidnum) { 04537 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04538 } 04539 if (cidname) { 04540 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04541 } 04542 gethostname(host, sizeof(host) - 1); 04543 04544 if (strchr(srcemail, '@')) { 04545 ast_copy_string(who, srcemail, sizeof(who)); 04546 } else { 04547 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04548 } 04549 04550 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04551 if (greeting_attachment) { 04552 *greeting_attachment++ = '\0'; 04553 } 04554 04555 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04556 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04557 fprintf(p, "Date: %s" ENDL, date); 04558 04559 /* Set date format for voicemail mail */ 04560 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04561 04562 if (!ast_strlen_zero(fromstring)) { 04563 struct ast_channel *ast; 04564 if ((ast = ast_dummy_channel_alloc())) { 04565 char *ptr; 04566 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04567 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04568 04569 if (check_mime(ast_str_buffer(str1))) { 04570 int first_line = 1; 04571 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04572 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04573 *ptr = '\0'; 04574 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04575 first_line = 0; 04576 /* Substring is smaller, so this will never grow */ 04577 ast_str_set(&str2, 0, "%s", ptr + 1); 04578 } 04579 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04580 } else { 04581 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04582 } 04583 ast = ast_channel_unref(ast); 04584 } else { 04585 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04586 } 04587 } else { 04588 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04589 } 04590 04591 if (check_mime(vmu->fullname)) { 04592 int first_line = 1; 04593 char *ptr; 04594 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04595 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04596 *ptr = '\0'; 04597 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04598 first_line = 0; 04599 /* Substring is smaller, so this will never grow */ 04600 ast_str_set(&str2, 0, "%s", ptr + 1); 04601 } 04602 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04603 } else { 04604 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04605 } 04606 04607 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04608 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04609 struct ast_channel *ast; 04610 if ((ast = ast_dummy_channel_alloc())) { 04611 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04612 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04613 if (check_mime(ast_str_buffer(str1))) { 04614 int first_line = 1; 04615 char *ptr; 04616 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04617 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04618 *ptr = '\0'; 04619 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04620 first_line = 0; 04621 /* Substring is smaller, so this will never grow */ 04622 ast_str_set(&str2, 0, "%s", ptr + 1); 04623 } 04624 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04625 } else { 04626 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04627 } 04628 ast = ast_channel_unref(ast); 04629 } else { 04630 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04631 } 04632 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04633 if (ast_strlen_zero(flag)) { 04634 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04635 } else { 04636 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04637 } 04638 } else { 04639 if (ast_strlen_zero(flag)) { 04640 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04641 } else { 04642 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04643 } 04644 } 04645 04646 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04647 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04648 if (imap) { 04649 /* additional information needed for IMAP searching */ 04650 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04651 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04652 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04653 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04654 #ifdef IMAP_STORAGE 04655 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04656 #else 04657 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04658 #endif 04659 /* flag added for Urgent */ 04660 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04661 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04662 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04663 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04664 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04665 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04666 if (!ast_strlen_zero(category)) { 04667 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04668 } else { 04669 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04670 } 04671 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04672 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04673 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04674 } 04675 if (!ast_strlen_zero(cidnum)) { 04676 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04677 } 04678 if (!ast_strlen_zero(cidname)) { 04679 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04680 } 04681 fprintf(p, "MIME-Version: 1.0" ENDL); 04682 if (attach_user_voicemail) { 04683 /* Something unique. */ 04684 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04685 (int) getpid(), (unsigned int) ast_random()); 04686 04687 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04688 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04689 fprintf(p, "--%s" ENDL, bound); 04690 } 04691 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04692 if (emailbody || vmu->emailbody) { 04693 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04694 struct ast_channel *ast; 04695 if ((ast = ast_dummy_channel_alloc())) { 04696 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04697 ast_str_substitute_variables(&str1, 0, ast, e_body); 04698 #ifdef IMAP_STORAGE 04699 { 04700 /* Convert body to native line terminators for IMAP backend */ 04701 char *line = ast_str_buffer(str1), *next; 04702 do { 04703 /* Terminate line before outputting it to the file */ 04704 if ((next = strchr(line, '\n'))) { 04705 *next++ = '\0'; 04706 } 04707 fprintf(p, "%s" ENDL, line); 04708 line = next; 04709 } while (!ast_strlen_zero(line)); 04710 } 04711 #else 04712 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04713 #endif 04714 ast = ast_channel_unref(ast); 04715 } else { 04716 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04717 } 04718 } else if (msgnum > -1) { 04719 if (strcmp(vmu->mailbox, mailbox)) { 04720 /* Forwarded type */ 04721 struct ast_config *msg_cfg; 04722 const char *v; 04723 int inttime; 04724 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04725 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04726 /* Retrieve info from VM attribute file */ 04727 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04728 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04729 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04730 strcat(fromfile, ".txt"); 04731 } 04732 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04733 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04734 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04735 } 04736 04737 /* You might be tempted to do origdate, except that a) it's in the wrong 04738 * format, and b) it's missing for IMAP recordings. */ 04739 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04740 struct timeval tv = { inttime, }; 04741 struct ast_tm tm; 04742 ast_localtime(&tv, &tm, NULL); 04743 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04744 } 04745 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04746 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04747 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04748 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04749 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04750 date, origcallerid, origdate); 04751 ast_config_destroy(msg_cfg); 04752 } else { 04753 goto plain_message; 04754 } 04755 } else { 04756 plain_message: 04757 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04758 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04759 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04760 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04761 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04762 } 04763 } else { 04764 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04765 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04766 } 04767 04768 if (imap || attach_user_voicemail) { 04769 if (!ast_strlen_zero(attach2)) { 04770 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04771 ast_debug(5, "creating second attachment filename %s\n", filename); 04772 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04773 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04774 ast_debug(5, "creating attachment filename %s\n", filename); 04775 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04776 } else { 04777 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04778 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04779 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04780 } 04781 } 04782 ast_free(str1); 04783 ast_free(str2); 04784 }
static int make_file | ( | char * | dest, | |
const int | len, | |||
const char * | dir, | |||
const int | num | |||
) | [static] |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.
dest | The variable to hold the output generated path expression. This buffer should be of size PATH_MAX. | |
len | The length of the path string that was written out. | |
dir | ||
num |
Definition at line 1652 of file app_voicemail.c.
Referenced by advanced_options(), close_mailbox(), copy_message(), forward_message(), make_email_file(), notify_new_message(), play_message(), prep_email_sub_vars(), resequence_mailbox(), save_to_folder(), vm_execmain(), and vm_forwardoptions().
01653 { 01654 return snprintf(dest, len, "%s/msg%04d", dir, num); 01655 }
static int manager_list_voicemail_users | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager list voicemail users command.
Definition at line 11602 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::list, 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().
11603 { 11604 struct ast_vm_user *vmu = NULL; 11605 const char *id = astman_get_header(m, "ActionID"); 11606 char actionid[128] = ""; 11607 11608 if (!ast_strlen_zero(id)) 11609 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11610 11611 AST_LIST_LOCK(&users); 11612 11613 if (AST_LIST_EMPTY(&users)) { 11614 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11615 AST_LIST_UNLOCK(&users); 11616 return RESULT_SUCCESS; 11617 } 11618 11619 astman_send_ack(s, m, "Voicemail user list will follow"); 11620 11621 AST_LIST_TRAVERSE(&users, vmu, list) { 11622 char dirname[256]; 11623 11624 #ifdef IMAP_STORAGE 11625 int new, old; 11626 inboxcount(vmu->mailbox, &new, &old); 11627 #endif 11628 11629 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11630 astman_append(s, 11631 "%s" 11632 "Event: VoicemailUserEntry\r\n" 11633 "VMContext: %s\r\n" 11634 "VoiceMailbox: %s\r\n" 11635 "Fullname: %s\r\n" 11636 "Email: %s\r\n" 11637 "Pager: %s\r\n" 11638 "ServerEmail: %s\r\n" 11639 "MailCommand: %s\r\n" 11640 "Language: %s\r\n" 11641 "TimeZone: %s\r\n" 11642 "Callback: %s\r\n" 11643 "Dialout: %s\r\n" 11644 "UniqueID: %s\r\n" 11645 "ExitContext: %s\r\n" 11646 "SayDurationMinimum: %d\r\n" 11647 "SayEnvelope: %s\r\n" 11648 "SayCID: %s\r\n" 11649 "AttachMessage: %s\r\n" 11650 "AttachmentFormat: %s\r\n" 11651 "DeleteMessage: %s\r\n" 11652 "VolumeGain: %.2f\r\n" 11653 "CanReview: %s\r\n" 11654 "CallOperator: %s\r\n" 11655 "MaxMessageCount: %d\r\n" 11656 "MaxMessageLength: %d\r\n" 11657 "NewMessageCount: %d\r\n" 11658 #ifdef IMAP_STORAGE 11659 "OldMessageCount: %d\r\n" 11660 "IMAPUser: %s\r\n" 11661 #endif 11662 "\r\n", 11663 actionid, 11664 vmu->context, 11665 vmu->mailbox, 11666 vmu->fullname, 11667 vmu->email, 11668 vmu->pager, 11669 vmu->serveremail, 11670 vmu->mailcmd, 11671 vmu->language, 11672 vmu->zonetag, 11673 vmu->callback, 11674 vmu->dialout, 11675 vmu->uniqueid, 11676 vmu->exit, 11677 vmu->saydurationm, 11678 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11679 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11680 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11681 vmu->attachfmt, 11682 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11683 vmu->volgain, 11684 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11685 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11686 vmu->maxmsg, 11687 vmu->maxsecs, 11688 #ifdef IMAP_STORAGE 11689 new, old, vmu->imapuser 11690 #else 11691 count_messages(vmu, dirname) 11692 #endif 11693 ); 11694 } 11695 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11696 11697 AST_LIST_UNLOCK(&users); 11698 11699 return RESULT_SUCCESS; 11700 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11436 of file app_voicemail.c.
References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), poll_cond, poll_freq, poll_lock, poll_subscribed_mailboxes(), and poll_thread_run.
Referenced by start_poll_thread().
11437 { 11438 while (poll_thread_run) { 11439 struct timespec ts = { 0, }; 11440 struct timeval wait; 11441 11442 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11443 ts.tv_sec = wait.tv_sec; 11444 ts.tv_nsec = wait.tv_usec * 1000; 11445 11446 ast_mutex_lock(&poll_lock); 11447 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11448 ast_mutex_unlock(&poll_lock); 11449 11450 if (!poll_thread_run) 11451 break; 11452 11453 poll_subscribed_mailboxes(); 11454 } 11455 11456 return NULL; 11457 }
static const char* mbox | ( | struct ast_vm_user * | vmu, | |
int | id | |||
) | [static] |
Definition at line 1713 of file app_voicemail.c.
References ARRAY_LEN.
Referenced by acf_mailbox_exists(), add_peer_mailboxes(), adsi_load_vmail(), copy_message(), get_folder(), has_voicemail(), notify_new_message(), open_mailbox(), save_to_folder(), vm_box_exists(), and vm_execmain().
01714 { 01715 #ifdef IMAP_STORAGE 01716 if (vmu && id == 0) { 01717 return vmu->imapfolder; 01718 } 01719 #endif 01720 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01721 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 5367 of file app_voicemail.c.
References __has_voicemail().
Referenced by load_module().
05368 { 05369 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05370 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11459 of file app_voicemail.c.
References ast_free, and mwi_sub.
Referenced by handle_unsubscribe().
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11537 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(), handle_subscribe(), LOG_ERROR, and mwi_subscription_tps.
Referenced by start_poll_thread().
11538 { 11539 struct mwi_sub_task *mwist; 11540 11541 if (ast_event_get_type(event) != AST_EVENT_SUB) 11542 return; 11543 11544 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11545 return; 11546 11547 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11548 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11549 return; 11550 } 11551 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11552 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11553 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11554 11555 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11556 ast_free(mwist); 11557 } 11558 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11521 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().
11522 { 11523 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11524 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 11525 return; 11526 11527 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11528 return; 11529 11530 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11531 *uniqueid = u; 11532 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11533 ast_free(uniqueid); 11534 } 11535 }
static int notify_new_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms, | |||
int | msgnum, | |||
long | duration, | |||
char * | fmt, | |||
char * | cidnum, | |||
char * | cidname, | |||
const char * | flag | |||
) | [static] |
Sends email notification that a user has a new voicemail waiting for them.
chan | ||
vmu | ||
vms | ||
msgnum | ||
duration | ||
fmt | ||
cidnum | The Caller ID phone number value. | |
cidname | The Caller ID name value. | |
flag |
Definition at line 7032 of file app_voicemail.c.
References ast_app_has_voicemail(), ast_app_inboxcount2(), ast_channel_lock, ast_channel_unlock, ast_log(), ast_manager_event, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::attachfmt, ast_vm_user::context, vm_state::curmsg, DELETE, DISPOSE, ast_vm_user::email, EVENT_FLAG_CALL, ast_vm_user::mailbox, make_dir(), make_file(), mbox(), vm_state::newmessages, ast_vm_user::pager, pbx_builtin_getvar_helper(), queue_mwi_event(), RETRIEVE, run_externnotify(), sendmail(), sendpage(), ast_vm_user::serveremail, serveremail, strsep(), VM_ATTACH, vm_delete(), VM_DELETE, and VM_SPOOL_DIR.
07033 { 07034 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07035 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07036 const char *category; 07037 char *myserveremail = serveremail; 07038 07039 ast_channel_lock(chan); 07040 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07041 category = ast_strdupa(category); 07042 } 07043 ast_channel_unlock(chan); 07044 07045 #ifndef IMAP_STORAGE 07046 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07047 #else 07048 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07049 #endif 07050 make_file(fn, sizeof(fn), todir, msgnum); 07051 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07052 07053 if (!ast_strlen_zero(vmu->attachfmt)) { 07054 if (strstr(fmt, vmu->attachfmt)) 07055 fmt = vmu->attachfmt; 07056 else 07057 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); 07058 } 07059 07060 /* Attach only the first format */ 07061 fmt = ast_strdupa(fmt); 07062 stringp = fmt; 07063 strsep(&stringp, "|"); 07064 07065 if (!ast_strlen_zero(vmu->serveremail)) 07066 myserveremail = vmu->serveremail; 07067 07068 if (!ast_strlen_zero(vmu->email)) { 07069 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07070 07071 if (attach_user_voicemail) 07072 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07073 07074 /* XXX possible imap issue, should category be NULL XXX */ 07075 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07076 07077 if (attach_user_voicemail) 07078 DISPOSE(todir, msgnum); 07079 } 07080 07081 if (!ast_strlen_zero(vmu->pager)) { 07082 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07083 } 07084 07085 if (ast_test_flag(vmu, VM_DELETE)) 07086 DELETE(todir, msgnum, fn, vmu); 07087 07088 /* Leave voicemail for someone */ 07089 if (ast_app_has_voicemail(ext_context, NULL)) 07090 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07091 07092 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07093 07094 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s@%s\r\nWaiting: %d\r\nNew: %d\r\nOld: %d\r\n", vmu->mailbox, vmu->context, ast_app_has_voicemail(ext_context, NULL), newmsgs, oldmsgs); 07095 run_externnotify(vmu->context, vmu->mailbox, flag); 07096 07097 #ifdef IMAP_STORAGE 07098 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07099 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07100 vm_imap_delete(NULL, vms->curmsg, vmu); 07101 vms->newmessages--; /* Fix new message count */ 07102 } 07103 #endif 07104 07105 return 0; 07106 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4237 of file app_voicemail.c.
References BASELINELEN, ENDL, and baseio::linelength.
Referenced by base_encode().
04238 { 04239 if (bio->linelength >= BASELINELEN) { 04240 if (fputs(ENDL, so) == EOF) { 04241 return -1; 04242 } 04243 04244 bio->linelength = 0; 04245 } 04246 04247 if (putc(((unsigned char) c), so) == EOF) { 04248 return -1; 04249 } 04250 04251 bio->linelength++; 04252 04253 return 1; 04254 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7877 of file app_voicemail.c.
References ast_copy_string(), ast_log(), AST_LOG_ERROR, ast_unlock_path(), ast_vm_user::context, count_messages(), create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, last_message_index(), vm_state::lastmsg, LOG_NOTICE, ast_vm_user::maxmsg, mbox(), resequence_mailbox(), vm_state::username, vm_allocate_dh(), vm_lock_path(), and vm_state::vmbox.
Referenced by vm_execmain().
07878 { 07879 int count_msg, last_msg; 07880 07881 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07882 07883 /* Rename the member vmbox HERE so that we don't try to return before 07884 * we know what's going on. 07885 */ 07886 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07887 07888 /* Faster to make the directory than to check if it exists. */ 07889 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07890 07891 /* traverses directory using readdir (or select query for ODBC) */ 07892 count_msg = count_messages(vmu, vms->curdir); 07893 if (count_msg < 0) { 07894 return count_msg; 07895 } else { 07896 vms->lastmsg = count_msg - 1; 07897 } 07898 07899 if (vm_allocate_dh(vms, vmu, count_msg)) { 07900 return -1; 07901 } 07902 07903 /* 07904 The following test is needed in case sequencing gets messed up. 07905 There appears to be more than one way to mess up sequence, so 07906 we will not try to find all of the root causes--just fix it when 07907 detected. 07908 */ 07909 07910 if (vm_lock_path(vms->curdir)) { 07911 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07912 return ERROR_LOCK_PATH; 07913 } 07914 07915 /* for local storage, checks directory for messages up to maxmsg limit */ 07916 last_msg = last_message_index(vmu, vms->curdir); 07917 ast_unlock_path(vms->curdir); 07918 07919 if (last_msg < -1) { 07920 return last_msg; 07921 } else if (vms->lastmsg != last_msg) { 07922 ast_log(LOG_NOTICE, "Resequencing Mailbox: %s, expected %d but found %d message(s) in box with max threshold of %d.\n", vms->curdir, last_msg + 1, vms->lastmsg + 1, vmu->maxmsg); 07923 resequence_mailbox(vmu, vms->curdir, count_msg); 07924 } 07925 07926 return 0; 07927 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7655 of file app_voicemail.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::heard, ast_channel::language, vm_state::lastmsg, LOG_WARNING, ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, VM_ENVELOPE, VM_SAYCID, VM_SAYDURATION, wait_file(), and wait_file2().
Referenced by vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_browse_messages_vi(), vm_browse_messages_zh(), and vm_execmain().
07656 { 07657 int res = 0; 07658 char filename[256], *cid; 07659 const char *origtime, *context, *category, *duration, *flag; 07660 struct ast_config *msg_cfg; 07661 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07662 07663 vms->starting = 0; 07664 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07665 adsi_message(chan, vms); 07666 if (!vms->curmsg) { 07667 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07668 } else if (vms->curmsg == vms->lastmsg) { 07669 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07670 } 07671 07672 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07673 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07674 msg_cfg = ast_config_load(filename, config_flags); 07675 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07676 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07677 return 0; 07678 } 07679 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07680 07681 /* Play the word urgent if we are listening to urgent messages */ 07682 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07683 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07684 } 07685 07686 if (!res) { 07687 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07688 /* POLISH syntax */ 07689 if (!strncasecmp(chan->language, "pl", 2)) { 07690 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07691 int ten, one; 07692 char nextmsg[256]; 07693 ten = (vms->curmsg + 1) / 10; 07694 one = (vms->curmsg + 1) % 10; 07695 07696 if (vms->curmsg < 20) { 07697 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07698 res = wait_file2(chan, vms, nextmsg); 07699 } else { 07700 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07701 res = wait_file2(chan, vms, nextmsg); 07702 if (one > 0) { 07703 if (!res) { 07704 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07705 res = wait_file2(chan, vms, nextmsg); 07706 } 07707 } 07708 } 07709 } 07710 if (!res) 07711 res = wait_file2(chan, vms, "vm-message"); 07712 /* HEBREW syntax */ 07713 } else if (!strncasecmp(chan->language, "he", 2)) { 07714 if (!vms->curmsg) { 07715 res = wait_file2(chan, vms, "vm-message"); 07716 res = wait_file2(chan, vms, "vm-first"); 07717 } else if (vms->curmsg == vms->lastmsg) { 07718 res = wait_file2(chan, vms, "vm-message"); 07719 res = wait_file2(chan, vms, "vm-last"); 07720 } else { 07721 res = wait_file2(chan, vms, "vm-message"); 07722 res = wait_file2(chan, vms, "vm-number"); 07723 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07724 } 07725 /* VIETNAMESE syntax */ 07726 } else if (!strncasecmp(chan->language, "vi", 2)) { 07727 if (!vms->curmsg) { 07728 res = wait_file2(chan, vms, "vm-message"); 07729 res = wait_file2(chan, vms, "vm-first"); 07730 } else if (vms->curmsg == vms->lastmsg) { 07731 res = wait_file2(chan, vms, "vm-message"); 07732 res = wait_file2(chan, vms, "vm-last"); 07733 } else { 07734 res = wait_file2(chan, vms, "vm-message"); 07735 res = wait_file2(chan, vms, "vm-number"); 07736 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07737 } 07738 } else { 07739 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07740 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07741 } else { /* DEFAULT syntax */ 07742 res = wait_file2(chan, vms, "vm-message"); 07743 } 07744 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07745 if (!res) { 07746 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07747 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07748 } 07749 } 07750 } 07751 } 07752 07753 if (!msg_cfg) { 07754 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07755 return 0; 07756 } 07757 07758 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07759 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07760 DISPOSE(vms->curdir, vms->curmsg); 07761 ast_config_destroy(msg_cfg); 07762 return 0; 07763 } 07764 07765 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07766 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07767 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07768 07769 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07770 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07771 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07772 if (!res) { 07773 res = play_message_category(chan, category); 07774 } 07775 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07776 res = play_message_datetime(chan, vmu, origtime, filename); 07777 } 07778 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07779 res = play_message_callerid(chan, vms, cid, context, 0); 07780 } 07781 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07782 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07783 } 07784 /* Allow pressing '1' to skip envelope / callerid */ 07785 if (res == '1') { 07786 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07787 res = 0; 07788 } 07789 ast_config_destroy(msg_cfg); 07790 07791 if (!res) { 07792 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07793 vms->heard[vms->curmsg] = 1; 07794 #ifdef IMAP_STORAGE 07795 /*IMAP storage stores any prepended message from a forward 07796 * as a separate file from the rest of the message 07797 */ 07798 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07799 wait_file(chan, vms, vms->introfn); 07800 } 07801 #endif 07802 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07803 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07804 res = 0; 07805 } 07806 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07807 } 07808 DISPOSE(vms->curdir, vms->curmsg); 07809 return res; 07810 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7541 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, ast_channel::language, MAX_NUM_CID_CONTEXTS, name, VM_SPOOL_DIR, and wait_file2().
Referenced by advanced_options(), and play_message().
07542 { 07543 int res = 0; 07544 int i; 07545 char *callerid, *name; 07546 char prefile[PATH_MAX] = ""; 07547 07548 07549 /* If voicemail cid is not enabled, or we didn't get cid or context from 07550 * the attribute file, leave now. 07551 * 07552 * TODO Still need to change this so that if this function is called by the 07553 * message envelope (and someone is explicitly requesting to hear the CID), 07554 * it does not check to see if CID is enabled in the config file. 07555 */ 07556 if ((cid == NULL)||(context == NULL)) 07557 return res; 07558 07559 /* Strip off caller ID number from name */ 07560 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07561 ast_callerid_parse(cid, &name, &callerid); 07562 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07563 /* Check for internal contexts and only */ 07564 /* say extension when the call didn't come from an internal context in the list */ 07565 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07566 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07567 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07568 break; 07569 } 07570 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07571 if (!res) { 07572 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07573 if (!ast_strlen_zero(prefile)) { 07574 /* See if we can find a recorded name for this person instead of their extension number */ 07575 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07576 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07577 if (!callback) 07578 res = wait_file2(chan, vms, "vm-from"); 07579 res = ast_stream_and_wait(chan, prefile, ""); 07580 } else { 07581 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07582 /* Say "from extension" as one saying to sound smoother */ 07583 if (!callback) 07584 res = wait_file2(chan, vms, "vm-from-extension"); 07585 res = ast_say_digit_str(chan, callerid, "", chan->language); 07586 } 07587 } 07588 } 07589 } else if (!res) { 07590 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07591 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07592 if (!callback) 07593 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07594 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07595 } 07596 } else { 07597 /* Number unknown */ 07598 ast_debug(1, "VM-CID: From an unknown number\n"); 07599 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07600 res = wait_file2(chan, vms, "vm-unknown-caller"); 07601 } 07602 return res; 07603 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7452 of file app_voicemail.c.
References ast_log(), ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
07453 { 07454 int res = 0; 07455 07456 if (!ast_strlen_zero(category)) 07457 res = ast_play_and_wait(chan, category); 07458 07459 if (res) { 07460 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07461 res = 0; 07462 } 07463 07464 return res; 07465 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7467 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_say_date_with_format, ast_strlen_zero(), ast_tvnow(), ast_channel::language, vm_zone::list, 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().
07468 { 07469 int res = 0; 07470 struct vm_zone *the_zone = NULL; 07471 time_t t; 07472 07473 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07474 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07475 return 0; 07476 } 07477 07478 /* Does this user have a timezone specified? */ 07479 if (!ast_strlen_zero(vmu->zonetag)) { 07480 /* Find the zone in the list */ 07481 struct vm_zone *z; 07482 AST_LIST_LOCK(&zones); 07483 AST_LIST_TRAVERSE(&zones, z, list) { 07484 if (!strcmp(z->name, vmu->zonetag)) { 07485 the_zone = z; 07486 break; 07487 } 07488 } 07489 AST_LIST_UNLOCK(&zones); 07490 } 07491 07492 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07493 #if 0 07494 /* Set the DIFF_* variables */ 07495 ast_localtime(&t, &time_now, NULL); 07496 tv_now = ast_tvnow(); 07497 ast_localtime(&tv_now, &time_then, NULL); 07498 07499 /* Day difference */ 07500 if (time_now.tm_year == time_then.tm_year) 07501 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07502 else 07503 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07504 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07505 07506 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07507 #endif 07508 if (the_zone) { 07509 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07510 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07511 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07512 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07513 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07514 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07515 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); 07516 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07517 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07518 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07519 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07520 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07521 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07522 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07523 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); 07524 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07525 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07526 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07527 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07528 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07529 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' A 'digits/day' dB 'digits/year' Y 'digits/at' k 'hours' M 'minutes'", NULL); 07530 } else { 07531 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07532 } 07533 #if 0 07534 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07535 #endif 07536 return res; 07537 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7605 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, say_and_wait(), and wait_file2().
Referenced by play_message().
07606 { 07607 int res = 0; 07608 int durationm; 07609 int durations; 07610 /* Verify that we have a duration for the message */ 07611 if (duration == NULL) 07612 return res; 07613 07614 /* Convert from seconds to minutes */ 07615 durations = atoi(duration); 07616 durationm = (durations / 60); 07617 07618 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07619 07620 if ((!res) && (durationm >= minduration)) { 07621 res = wait_file2(chan, vms, "vm-duration"); 07622 07623 /* POLISH syntax */ 07624 if (!strncasecmp(chan->language, "pl", 2)) { 07625 div_t num = div(durationm, 10); 07626 07627 if (durationm == 1) { 07628 res = ast_play_and_wait(chan, "digits/1z"); 07629 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07630 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07631 if (num.rem == 2) { 07632 if (!num.quot) { 07633 res = ast_play_and_wait(chan, "digits/2-ie"); 07634 } else { 07635 res = say_and_wait(chan, durationm - 2 , chan->language); 07636 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07637 } 07638 } else { 07639 res = say_and_wait(chan, durationm, chan->language); 07640 } 07641 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07642 } else { 07643 res = say_and_wait(chan, durationm, chan->language); 07644 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07645 } 07646 /* DEFAULT syntax */ 07647 } else { 07648 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07649 res = wait_file2(chan, vms, "vm-minutes"); 07650 } 07651 } 07652 return res; 07653 }
static int play_record_review | ( | struct ast_channel * | chan, | |
char * | playfile, | |||
char * | recordfile, | |||
int | maxtime, | |||
char * | fmt, | |||
int | outsidecaller, | |||
struct ast_vm_user * | vmu, | |||
int * | duration, | |||
int * | sound_duration, | |||
const char * | unlockdir, | |||
signed char | record_gain, | |||
struct vm_state * | vms, | |||
char * | flag | |||
) | [static] |
Definition at line 13375 of file app_voicemail.c.
References acceptdtmf, ast_channel_setoption(), ast_copy_string(), AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, INTRO, ast_vm_user::mailbox, maxsilence, silencethreshold, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.
13378 { 13379 /* Record message & let caller review or re-record it, or set options if applicable */ 13380 int res = 0; 13381 int cmd = 0; 13382 int max_attempts = 3; 13383 int attempts = 0; 13384 int recorded = 0; 13385 int msg_exists = 0; 13386 signed char zero_gain = 0; 13387 char tempfile[PATH_MAX]; 13388 char *acceptdtmf = "#"; 13389 char *canceldtmf = ""; 13390 int canceleddtmf = 0; 13391 13392 /* Note that urgent and private are for flagging messages as such in the future */ 13393 13394 /* barf if no pointer passed to store duration in */ 13395 if (duration == NULL) { 13396 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13397 return -1; 13398 } 13399 13400 if (!outsidecaller) 13401 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13402 else 13403 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13404 13405 cmd = '3'; /* Want to start by recording */ 13406 13407 while ((cmd >= 0) && (cmd != 't')) { 13408 switch (cmd) { 13409 case '1': 13410 if (!msg_exists) { 13411 /* In this case, 1 is to record a message */ 13412 cmd = '3'; 13413 break; 13414 } else { 13415 /* Otherwise 1 is to save the existing message */ 13416 ast_verb(3, "Saving message as is\n"); 13417 if (!outsidecaller) 13418 ast_filerename(tempfile, recordfile, NULL); 13419 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13420 if (!outsidecaller) { 13421 /* Saves to IMAP server only if imapgreeting=yes */ 13422 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13423 DISPOSE(recordfile, -1); 13424 } 13425 cmd = 't'; 13426 return res; 13427 } 13428 case '2': 13429 /* Review */ 13430 ast_verb(3, "Reviewing the message\n"); 13431 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13432 break; 13433 case '3': 13434 msg_exists = 0; 13435 /* Record */ 13436 if (recorded == 1) 13437 ast_verb(3, "Re-recording the message\n"); 13438 else 13439 ast_verb(3, "Recording the message\n"); 13440 13441 if (recorded && outsidecaller) { 13442 cmd = ast_play_and_wait(chan, INTRO); 13443 cmd = ast_play_and_wait(chan, "beep"); 13444 } 13445 recorded = 1; 13446 /* 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 */ 13447 if (record_gain) 13448 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13449 if (ast_test_flag(vmu, VM_OPERATOR)) 13450 canceldtmf = "0"; 13451 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13452 if (strchr(canceldtmf, cmd)) { 13453 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13454 canceleddtmf = 1; 13455 } 13456 if (record_gain) 13457 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13458 if (cmd == -1) { 13459 /* User has hung up, no options to give */ 13460 if (!outsidecaller) { 13461 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13462 ast_filedelete(tempfile, NULL); 13463 } 13464 return cmd; 13465 } 13466 if (cmd == '0') { 13467 break; 13468 } else if (cmd == '*') { 13469 break; 13470 #if 0 13471 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13472 /* Message is too short */ 13473 ast_verb(3, "Message too short\n"); 13474 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13475 cmd = ast_filedelete(tempfile, NULL); 13476 break; 13477 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13478 /* Message is all silence */ 13479 ast_verb(3, "Nothing recorded\n"); 13480 cmd = ast_filedelete(tempfile, NULL); 13481 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13482 if (!cmd) 13483 cmd = ast_play_and_wait(chan, "vm-speakup"); 13484 break; 13485 #endif 13486 } else { 13487 /* If all is well, a message exists */ 13488 msg_exists = 1; 13489 cmd = 0; 13490 } 13491 break; 13492 case '4': 13493 if (outsidecaller) { /* only mark vm messages */ 13494 /* Mark Urgent */ 13495 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13496 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13497 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13498 strcpy(flag, "Urgent"); 13499 } else if (flag) { 13500 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13501 res = ast_play_and_wait(chan, "vm-urgent-removed"); 13502 strcpy(flag, ""); 13503 } else { 13504 ast_play_and_wait(chan, "vm-sorry"); 13505 } 13506 cmd = 0; 13507 } else { 13508 cmd = ast_play_and_wait(chan, "vm-sorry"); 13509 } 13510 break; 13511 case '5': 13512 case '6': 13513 case '7': 13514 case '8': 13515 case '9': 13516 case '*': 13517 case '#': 13518 cmd = ast_play_and_wait(chan, "vm-sorry"); 13519 break; 13520 #if 0 13521 /* XXX Commented out for the moment because of the dangers of deleting 13522 a message while recording (can put the message numbers out of sync) */ 13523 case '*': 13524 /* Cancel recording, delete message, offer to take another message*/ 13525 cmd = ast_play_and_wait(chan, "vm-deleted"); 13526 cmd = ast_filedelete(tempfile, NULL); 13527 if (outsidecaller) { 13528 res = vm_exec(chan, NULL); 13529 return res; 13530 } 13531 else 13532 return 1; 13533 #endif 13534 case '0': 13535 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13536 cmd = ast_play_and_wait(chan, "vm-sorry"); 13537 break; 13538 } 13539 if (msg_exists || recorded) { 13540 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13541 if (!cmd) 13542 cmd = ast_waitfordigit(chan, 3000); 13543 if (cmd == '1') { 13544 ast_filerename(tempfile, recordfile, NULL); 13545 ast_play_and_wait(chan, "vm-msgsaved"); 13546 cmd = '0'; 13547 } else if (cmd == '4') { 13548 if (flag) { 13549 ast_play_and_wait(chan, "vm-marked-urgent"); 13550 strcpy(flag, "Urgent"); 13551 } 13552 ast_play_and_wait(chan, "vm-msgsaved"); 13553 cmd = '0'; 13554 } else { 13555 ast_play_and_wait(chan, "vm-deleted"); 13556 DELETE(tempfile, -1, tempfile, vmu); 13557 cmd = '0'; 13558 } 13559 } 13560 return cmd; 13561 default: 13562 /* If the caller is an ouside caller, and the review option is enabled, 13563 allow them to review the message, but let the owner of the box review 13564 their OGM's */ 13565 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13566 return cmd; 13567 if (msg_exists) { 13568 cmd = ast_play_and_wait(chan, "vm-review"); 13569 if (!cmd && outsidecaller) { 13570 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13571 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13572 } else if (flag) { 13573 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13574 } 13575 } 13576 } else { 13577 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13578 if (!cmd) 13579 cmd = ast_waitfordigit(chan, 600); 13580 } 13581 13582 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13583 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13584 if (!cmd) 13585 cmd = ast_waitfordigit(chan, 600); 13586 } 13587 #if 0 13588 if (!cmd) 13589 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13590 #endif 13591 if (!cmd) 13592 cmd = ast_waitfordigit(chan, 6000); 13593 if (!cmd) { 13594 attempts++; 13595 } 13596 if (attempts > max_attempts) { 13597 cmd = 't'; 13598 } 13599 } 13600 } 13601 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13602 /* Hang up or timeout, so delete the recording. */ 13603 ast_filedelete(tempfile, NULL); 13604 } 13605 13606 if (cmd != 't' && outsidecaller) 13607 ast_play_and_wait(chan, "vm-goodbye"); 13608 13609 return cmd; 13610 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11408 of file app_voicemail.c.
References inboxcount2(), mwi_sub, queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11409 { 11410 int new = 0, old = 0, urgent = 0; 11411 11412 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11413 11414 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11415 mwi_sub->old_urgent = urgent; 11416 mwi_sub->old_new = new; 11417 mwi_sub->old_old = old; 11418 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11419 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11420 } 11421 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11423 of file app_voicemail.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), mwi_sub::entry, mwi_sub, and poll_subscribed_mailbox().
Referenced by mb_poll_thread().
11424 { 11425 struct mwi_sub *mwi_sub; 11426 11427 AST_RWLIST_RDLOCK(&mwi_subs); 11428 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11429 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11430 poll_subscribed_mailbox(mwi_sub); 11431 } 11432 } 11433 AST_RWLIST_UNLOCK(&mwi_subs); 11434 }
static void populate_defaults | ( | struct ast_vm_user * | vmu | ) | [static] |
Sets default voicemail system options to a voicemail user.
This applies select global settings to a newly created (dynamic) instance of a voicemail user.
Definition at line 1014 of file app_voicemail.c.
References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, ast_free, ast_vm_user::callback, callcontext, dialcontext, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, exitcontext, globalflags, ast_vm_user::locale, ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, saydurationminfo, ast_vm_user::volgain, and ast_vm_user::zonetag.
01015 { 01016 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 01017 vmu->passwordlocation = passwordlocation; 01018 if (saydurationminfo) { 01019 vmu->saydurationm = saydurationminfo; 01020 } 01021 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 01022 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 01023 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 01024 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 01025 ast_copy_string(vmu->locale, locale, sizeof(vmu->locale)); 01026 if (vmminsecs) { 01027 vmu->minsecs = vmminsecs; 01028 } 01029 if (vmmaxsecs) { 01030 vmu->maxsecs = vmmaxsecs; 01031 } 01032 if (maxmsg) { 01033 vmu->maxmsg = maxmsg; 01034 } 01035 if (maxdeletedmsg) { 01036 vmu->maxdeletedmsg = maxdeletedmsg; 01037 } 01038 vmu->volgain = volgain; 01039 ast_free(vmu->emailsubject); 01040 vmu->emailsubject = NULL; 01041 ast_free(vmu->emailbody); 01042 vmu->emailbody = NULL; 01043 #ifdef IMAP_STORAGE 01044 ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder)); 01045 #endif 01046 }
static void prep_email_sub_vars | ( | struct ast_channel * | ast, | |
struct ast_vm_user * | vmu, | |||
int | msgnum, | |||
char * | context, | |||
char * | mailbox, | |||
const char * | fromfolder, | |||
char * | cidnum, | |||
char * | cidname, | |||
char * | dur, | |||
char * | date, | |||
const char * | category, | |||
const char * | flag | |||
) | [static] |
Definition at line 4325 of file app_voicemail.c.
References ast_callerid_merge(), ast_callerid_split(), ast_config_destroy(), ast_config_load, ast_localtime(), ast_log(), ast_strdupa, ast_strftime_locale(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, config_flags, ast_vm_user::context, emaildateformat, ast_vm_user::fullname, ast_vm_user::locale, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, pbx_builtin_setvar_helper(), and S_OR.
04326 { 04327 char callerid[256]; 04328 char num[12]; 04329 char fromdir[256], fromfile[256]; 04330 struct ast_config *msg_cfg; 04331 const char *origcallerid, *origtime; 04332 char origcidname[80], origcidnum[80], origdate[80]; 04333 int inttime; 04334 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04335 04336 /* Prepare variables for substitution in email body and subject */ 04337 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04338 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04339 snprintf(num, sizeof(num), "%d", msgnum); 04340 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04341 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04342 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04343 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04344 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04345 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04346 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04347 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04348 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04349 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04350 04351 /* Retrieve info from VM attribute file */ 04352 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04353 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04354 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04355 strcat(fromfile, ".txt"); 04356 } 04357 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04358 if (option_debug > 0) { 04359 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04360 } 04361 return; 04362 } 04363 04364 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04365 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04366 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04367 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04368 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04369 } 04370 04371 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04372 struct timeval tv = { inttime, }; 04373 struct ast_tm tm; 04374 ast_localtime(&tv, &tm, NULL); 04375 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04376 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04377 } 04378 ast_config_destroy(msg_cfg); 04379 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 6995 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().
06996 { 06997 struct ast_event *event; 06998 char *mailbox, *context; 06999 07000 /* Strip off @default */ 07001 context = mailbox = ast_strdupa(box); 07002 strsep(&context, "@"); 07003 if (ast_strlen_zero(context)) 07004 context = "default"; 07005 07006 if (!(event = ast_event_new(AST_EVENT_MWI, 07007 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 07008 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 07009 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 07010 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 07011 AST_EVENT_IE_END))) { 07012 return; 07013 } 07014 07015 ast_event_queue_and_cache(event); 07016 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12501 of file app_voicemail.c.
References ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), config_flags, and LOG_NOTICE.
Referenced by actual_load_config(), and append_mailbox().
12501 { 12502 struct ast_config *pwconf; 12503 struct ast_flags config_flags = { 0 }; 12504 12505 pwconf = ast_config_load(secretfn, config_flags); 12506 if (pwconf) { 12507 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12508 if (val) { 12509 ast_copy_string(password, val, passwordlen); 12510 return; 12511 } 12512 } 12513 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12514 }
static int reload | ( | void | ) | [static] |
Definition at line 13022 of file app_voicemail.c.
References load_config().
13023 { 13024 return load_config(1); 13025 }
static void rename_file | ( | char * | sfn, | |
char * | dfn | |||
) | [static] |
Renames a message in a mailbox folder.
sfn | The path to the mailbox information and data file to be renamed. | |
dfn | The path for where the message data and information files will be renamed to. |
Definition at line 3994 of file app_voicemail.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
03995 { 03996 char stxt[PATH_MAX]; 03997 char dtxt[PATH_MAX]; 03998 ast_filerename(sfn, dfn, NULL); 03999 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 04000 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 04001 if (ast_check_realtime("voicemail_data")) { 04002 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 04003 } 04004 rename(stxt, dtxt); 04005 }
static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6137 of file app_voicemail.c.
References ast_unlock_path(), ast_vm_user::context, ERROR_LOCK_PATH, EXISTS, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, RENAME, and vm_lock_path().
Referenced by open_mailbox().
06138 { 06139 /* we know the actual number of messages, so stop process when number is hit */ 06140 06141 int x, dest; 06142 char sfn[PATH_MAX]; 06143 char dfn[PATH_MAX]; 06144 06145 if (vm_lock_path(dir)) { 06146 return ERROR_LOCK_PATH; 06147 } 06148 06149 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06150 make_file(sfn, sizeof(sfn), dir, x); 06151 if (EXISTS(dir, x, sfn, NULL)) { 06152 06153 if (x != dest) { 06154 make_file(dfn, sizeof(dfn), dir, dest); 06155 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06156 } 06157 06158 dest++; 06159 } 06160 } 06161 ast_unlock_path(dir); 06162 06163 return dest; 06164 }
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 1480 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::list, ast_vm_user::mailbox, and ast_vm_user::password.
Referenced by vm_change_password(), and vm_change_password_shell().
01481 { 01482 /* This function could be made to generate one from a database, too */ 01483 struct ast_vm_user *cur; 01484 int res = -1; 01485 AST_LIST_LOCK(&users); 01486 AST_LIST_TRAVERSE(&users, cur, list) { 01487 if ((!context || !strcasecmp(context, cur->context)) && 01488 (!strcasecmp(mailbox, cur->mailbox))) 01489 break; 01490 } 01491 if (cur) { 01492 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01493 res = 0; 01494 } 01495 AST_LIST_UNLOCK(&users); 01496 return res; 01497 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 5510 of file app_voicemail.c.
References ast_app_has_voicemail(), ast_copy_string(), ast_debug, ast_log(), AST_LOG_ERROR, ast_safe_system(), ast_smdi_mwi_message_destroy(), ast_smdi_mwi_message_wait_station(), ast_smdi_mwi_set(), ast_smdi_mwi_unset(), ast_strlen_zero(), ASTOBJ_UNREF, ast_smdi_mwi_message::cause, externnotify, ast_smdi_mwi_message::fwd_st, inboxcount2(), smdi_iface, and SMDI_MWI_WAIT_TIMEOUT.
05511 { 05512 char arguments[255]; 05513 char ext_context[256] = ""; 05514 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05515 struct ast_smdi_mwi_message *mwi_msg; 05516 05517 if (!ast_strlen_zero(context)) 05518 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05519 else 05520 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05521 05522 if (smdi_iface) { 05523 if (ast_app_has_voicemail(ext_context, NULL)) 05524 ast_smdi_mwi_set(smdi_iface, extension); 05525 else 05526 ast_smdi_mwi_unset(smdi_iface, extension); 05527 05528 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05529 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05530 if (!strncmp(mwi_msg->cause, "INV", 3)) 05531 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05532 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05533 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05534 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05535 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05536 } else { 05537 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05538 } 05539 } 05540 05541 if (!ast_strlen_zero(externnotify)) { 05542 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05543 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05544 } else { 05545 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05546 ast_debug(1, "Executing %s\n", arguments); 05547 ast_safe_system(arguments); 05548 } 05549 } 05550 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6174 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_NOTICE, ast_mutex_lock, ast_mutex_unlock, ast_unlock_path(), COPY, create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, EXISTS, last_message_index(), make_file(), mbox(), NEW_FOLDER, OLD_FOLDER, RENAME, vm_state::username, and vm_lock_path().
Referenced by close_mailbox(), and vm_execmain().
06175 { 06176 #ifdef IMAP_STORAGE 06177 /* we must use mbox(x) folder names, and copy the message there */ 06178 /* simple. huh? */ 06179 char sequence[10]; 06180 char mailbox[256]; 06181 int res; 06182 06183 /* get the real IMAP message number for this message */ 06184 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06185 06186 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06187 ast_mutex_lock(&vms->lock); 06188 /* if save to Old folder, put in INBOX as read */ 06189 if (box == OLD_FOLDER) { 06190 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06191 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06192 } else if (box == NEW_FOLDER) { 06193 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06194 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06195 } 06196 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06197 ast_mutex_unlock(&vms->lock); 06198 return 0; 06199 } 06200 /* Create the folder if it don't exist */ 06201 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06202 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06203 if (mail_create(vms->mailstream, mailbox) == NIL) 06204 ast_debug(5, "Folder exists.\n"); 06205 else 06206 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06207 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06208 ast_mutex_unlock(&vms->lock); 06209 return res; 06210 #else 06211 char *dir = vms->curdir; 06212 char *username = vms->username; 06213 char *context = vmu->context; 06214 char sfn[PATH_MAX]; 06215 char dfn[PATH_MAX]; 06216 char ddir[PATH_MAX]; 06217 const char *dbox = mbox(vmu, box); 06218 int x, i; 06219 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06220 06221 if (vm_lock_path(ddir)) 06222 return ERROR_LOCK_PATH; 06223 06224 x = last_message_index(vmu, ddir) + 1; 06225 06226 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06227 x--; 06228 for (i = 1; i <= x; i++) { 06229 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06230 make_file(sfn, sizeof(sfn), ddir, i); 06231 make_file(dfn, sizeof(dfn), ddir, i - 1); 06232 if (EXISTS(ddir, i, sfn, NULL)) { 06233 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06234 } else 06235 break; 06236 } 06237 } else { 06238 if (x >= vmu->maxmsg) { 06239 ast_unlock_path(ddir); 06240 return -1; 06241 } 06242 } 06243 make_file(sfn, sizeof(sfn), dir, msg); 06244 make_file(dfn, sizeof(dfn), ddir, x); 06245 if (strcmp(sfn, dfn)) { 06246 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06247 } 06248 ast_unlock_path(ddir); 06249 #endif 06250 return 0; 06251 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6167 of file app_voicemail.c.
References AST_DIGIT_ANY, and ast_say_number().
Referenced by play_message_duration(), vm_execmain(), vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_it(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_se(), vm_intro_vi(), and vm_intro_zh().
06168 { 06169 int d; 06170 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06171 return d; 06172 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12487 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, RETRIEVE, and VM_SPOOL_DIR.
Referenced by load_module(), and vmsayname_exec().
12488 { 12489 int res = -1; 12490 char dir[PATH_MAX]; 12491 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12492 ast_debug(2, "About to try retrieving name file %s\n", dir); 12493 RETRIEVE(dir, -1, mailbox, context); 12494 if (ast_fileexists(dir, NULL, NULL)) { 12495 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12496 } 12497 DISPOSE(dir, -1); 12498 return res; 12499 }
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 4840 of file app_voicemail.c.
References ast_debug, ast_log(), ast_safe_system(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::email, globalflags, ast_vm_user::mailbox, mailcmd, make_email_file(), strsep(), VM_ATTACH, and vm_mkftemp().
04841 { 04842 FILE *p = NULL; 04843 char tmp[80] = "/tmp/astmail-XXXXXX"; 04844 char tmp2[256]; 04845 char *stringp; 04846 04847 if (vmu && ast_strlen_zero(vmu->email)) { 04848 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04849 return(0); 04850 } 04851 04852 /* Mail only the first format */ 04853 format = ast_strdupa(format); 04854 stringp = format; 04855 strsep(&stringp, "|"); 04856 04857 if (!strcmp(format, "wav49")) 04858 format = "WAV"; 04859 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)); 04860 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04861 command hangs */ 04862 if ((p = vm_mkftemp(tmp)) == NULL) { 04863 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04864 return -1; 04865 } else { 04866 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04867 fclose(p); 04868 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04869 ast_safe_system(tmp2); 04870 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04871 } 04872 return 0; 04873 }
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 4875 of file app_voicemail.c.
References ast_channel_unref, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, ast_log(), ast_safe_system(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strftime_locale(), ast_strlen_zero(), check_mime(), ENDL, ast_vm_user::fullname, ast_vm_user::locale, mailcmd, MAXHOSTNAMELEN, pagerbody, pagerdateformat, pagerfromstring, pagersubject, prep_email_sub_vars(), S_OR, strip_control_and_high(), vm_mkftemp(), and vmu_tm().
Referenced by notify_new_message().
04876 { 04877 char enc_cidnum[256], enc_cidname[256]; 04878 char date[256]; 04879 char host[MAXHOSTNAMELEN] = ""; 04880 char who[256]; 04881 char dur[PATH_MAX]; 04882 char tmp[80] = "/tmp/astmail-XXXXXX"; 04883 char tmp2[PATH_MAX]; 04884 struct ast_tm tm; 04885 FILE *p; 04886 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04887 04888 if (!str1 || !str2) { 04889 ast_free(str1); 04890 ast_free(str2); 04891 return -1; 04892 } 04893 04894 if (cidnum) { 04895 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04896 } 04897 if (cidname) { 04898 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04899 } 04900 04901 if ((p = vm_mkftemp(tmp)) == NULL) { 04902 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04903 ast_free(str1); 04904 ast_free(str2); 04905 return -1; 04906 } 04907 gethostname(host, sizeof(host)-1); 04908 if (strchr(srcemail, '@')) { 04909 ast_copy_string(who, srcemail, sizeof(who)); 04910 } else { 04911 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04912 } 04913 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04914 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04915 fprintf(p, "Date: %s\n", date); 04916 04917 /* Reformat for custom pager format */ 04918 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04919 04920 if (!ast_strlen_zero(pagerfromstring)) { 04921 struct ast_channel *ast; 04922 if ((ast = ast_dummy_channel_alloc())) { 04923 char *ptr; 04924 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04925 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04926 04927 if (check_mime(ast_str_buffer(str1))) { 04928 int first_line = 1; 04929 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04930 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04931 *ptr = '\0'; 04932 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04933 first_line = 0; 04934 /* Substring is smaller, so this will never grow */ 04935 ast_str_set(&str2, 0, "%s", ptr + 1); 04936 } 04937 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04938 } else { 04939 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04940 } 04941 ast = ast_channel_unref(ast); 04942 } else { 04943 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04944 } 04945 } else { 04946 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04947 } 04948 04949 if (check_mime(vmu->fullname)) { 04950 int first_line = 1; 04951 char *ptr; 04952 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04953 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04954 *ptr = '\0'; 04955 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04956 first_line = 0; 04957 /* Substring is smaller, so this will never grow */ 04958 ast_str_set(&str2, 0, "%s", ptr + 1); 04959 } 04960 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04961 } else { 04962 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04963 } 04964 04965 if (!ast_strlen_zero(pagersubject)) { 04966 struct ast_channel *ast; 04967 if ((ast = ast_dummy_channel_alloc())) { 04968 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04969 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 04970 if (check_mime(ast_str_buffer(str1))) { 04971 int first_line = 1; 04972 char *ptr; 04973 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04974 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04975 *ptr = '\0'; 04976 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04977 first_line = 0; 04978 /* Substring is smaller, so this will never grow */ 04979 ast_str_set(&str2, 0, "%s", ptr + 1); 04980 } 04981 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04982 } else { 04983 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04984 } 04985 ast = ast_channel_unref(ast); 04986 } else { 04987 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04988 } 04989 } else { 04990 if (ast_strlen_zero(flag)) { 04991 fprintf(p, "Subject: New VM\n\n"); 04992 } else { 04993 fprintf(p, "Subject: New %s VM\n\n", flag); 04994 } 04995 } 04996 04997 if (pagerbody) { 04998 struct ast_channel *ast; 04999 if ((ast = ast_dummy_channel_alloc())) { 05000 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05001 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 05002 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 05003 ast = ast_channel_unref(ast); 05004 } else { 05005 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05006 } 05007 } else { 05008 fprintf(p, "New %s long %s msg in box %s\n" 05009 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 05010 } 05011 05012 fclose(p); 05013 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 05014 ast_safe_system(tmp2); 05015 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 05016 ast_free(str1); 05017 ast_free(str2); 05018 return 0; 05019 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 11065 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, SENTINEL, and var.
Referenced by handle_voicemail_show_users().
11066 { 11067 struct ast_config *cfg; 11068 const char *cat = NULL; 11069 11070 if (!(cfg = ast_load_realtime_multientry("voicemail", 11071 "context", context, SENTINEL))) { 11072 return CLI_FAILURE; 11073 } 11074 11075 ast_cli(fd, 11076 "\n" 11077 "=============================================================\n" 11078 "=== Configured Voicemail Users ==============================\n" 11079 "=============================================================\n" 11080 "===\n"); 11081 11082 while ((cat = ast_category_browse(cfg, cat))) { 11083 struct ast_variable *var = NULL; 11084 ast_cli(fd, 11085 "=== Mailbox ...\n" 11086 "===\n"); 11087 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11088 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11089 ast_cli(fd, 11090 "===\n" 11091 "=== ---------------------------------------------------------\n" 11092 "===\n"); 11093 } 11094 11095 ast_cli(fd, 11096 "=============================================================\n" 11097 "\n"); 11098 11099 ast_config_destroy(cfg); 11100 11101 return CLI_SUCCESS; 11102 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11560 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(), mwi_sub_sub, mwi_unsub_event_cb(), mwi_unsub_sub, poll_thread, and poll_thread_run.
Referenced by actual_load_config().
11561 { 11562 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11563 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11564 AST_EVENT_IE_END); 11565 11566 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11567 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11568 AST_EVENT_IE_END); 11569 11570 if (mwi_sub_sub) 11571 ast_event_report_subs(mwi_sub_sub); 11572 11573 poll_thread_run = 1; 11574 11575 ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL); 11576 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11578 of file app_voicemail.c.
References ast_cond_signal, ast_event_unsubscribe(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, mwi_sub_sub, mwi_unsub_sub, poll_cond, poll_lock, poll_thread, and poll_thread_run.
Referenced by actual_load_config(), and unload_module().
11579 { 11580 poll_thread_run = 0; 11581 11582 if (mwi_sub_sub) { 11583 ast_event_unsubscribe(mwi_sub_sub); 11584 mwi_sub_sub = NULL; 11585 } 11586 11587 if (mwi_unsub_sub) { 11588 ast_event_unsubscribe(mwi_unsub_sub); 11589 mwi_unsub_sub = NULL; 11590 } 11591 11592 ast_mutex_lock(&poll_lock); 11593 ast_cond_signal(&poll_cond); 11594 ast_mutex_unlock(&poll_lock); 11595 11596 pthread_join(poll_thread, NULL); 11597 11598 poll_thread = AST_PTHREADT_NULL; 11599 }
static char* strip_control_and_high | ( | const char * | input, | |
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Strips control and non 7-bit clean characters from input string.
Definition at line 984 of file app_voicemail.c.
Referenced by make_email_file(), and sendpage().
00985 { 00986 char *bufptr = buf; 00987 for (; *input; input++) { 00988 if (*input < 32) { 00989 continue; 00990 } 00991 *bufptr++ = *input; 00992 if (bufptr == buf + buflen - 1) { 00993 break; 00994 } 00995 } 00996 *bufptr = '\0'; 00997 return buf; 00998 }
static const char * substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 11724 of file app_voicemail.c.
References ast_log(), AST_LOG_NOTICE, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), and str.
Referenced by actual_load_config(), and apply_option().
11725 { 11726 char *current; 11727 11728 /* Add 16 for fudge factor */ 11729 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11730 11731 ast_str_reset(str); 11732 11733 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11734 for (current = (char *) value; *current; current++) { 11735 if (*current == '\\') { 11736 current++; 11737 if (!*current) { 11738 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11739 break; 11740 } 11741 switch (*current) { 11742 case '\\': 11743 ast_str_append(&str, 0, "\\"); 11744 break; 11745 case 'r': 11746 ast_str_append(&str, 0, "\r"); 11747 break; 11748 case 'n': 11749 #ifdef IMAP_STORAGE 11750 if (!str->used || str->str[str->used - 1] != '\r') { 11751 ast_str_append(&str, 0, "\r"); 11752 } 11753 #endif 11754 ast_str_append(&str, 0, "\n"); 11755 break; 11756 case 't': 11757 ast_str_append(&str, 0, "\t"); 11758 break; 11759 default: 11760 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11761 break; 11762 } 11763 } else { 11764 ast_str_append(&str, 0, "%c", *current); 11765 } 11766 } 11767 11768 return ast_str_buffer(str); 11769 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13027 of file app_voicemail.c.
References ao2_ref, app, app2, app3, app4, ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_data_unregister, ast_manager_unregister(), AST_PTHREADT_NULL, ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_uninstall_vm_functions(), ast_unload_realtime(), ast_unregister_application(), cli_voicemail, free_vm_users(), free_vm_zones(), inprocess_container, mailbox_exists_acf, mwi_subscription_tps, poll_thread, sayname_app, and stop_poll_thread().
13028 { 13029 int res; 13030 13031 res = ast_unregister_application(app); 13032 res |= ast_unregister_application(app2); 13033 res |= ast_unregister_application(app3); 13034 res |= ast_unregister_application(app4); 13035 res |= ast_unregister_application(sayname_app); 13036 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13037 res |= ast_manager_unregister("VoicemailUsersList"); 13038 res |= ast_data_unregister(NULL); 13039 #ifdef TEST_FRAMEWORK 13040 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13041 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13042 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13043 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13044 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13045 #endif 13046 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13047 ast_uninstall_vm_functions(); 13048 ao2_ref(inprocess_container, -1); 13049 13050 if (poll_thread != AST_PTHREADT_NULL) 13051 stop_poll_thread(); 13052 13053 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13054 ast_unload_realtime("voicemail"); 13055 ast_unload_realtime("voicemail_data"); 13056 13057 free_vm_users(); 13058 free_vm_zones(); 13059 return res; 13060 }
static int vm_allocate_dh | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | count_msg | |||
) | [static] |
Definition at line 1750 of file app_voicemail.c.
References ast_calloc, ast_realloc, vm_state::deleted, vm_state::dh_arraysize, vm_state::heard, and ast_vm_user::maxmsg.
Referenced by open_mailbox().
01750 { 01751 01752 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01753 if (!vms->dh_arraysize) { 01754 /* initial allocation */ 01755 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01756 return -1; 01757 } 01758 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01759 return -1; 01760 } 01761 vms->dh_arraysize = arraysize; 01762 } else if (vms->dh_arraysize < arraysize) { 01763 if (!(vms->deleted = ast_realloc(vms->deleted, arraysize * sizeof(int)))) { 01764 return -1; 01765 } 01766 if (!(vms->heard = ast_realloc(vms->heard, arraysize * sizeof(int)))) { 01767 return -1; 01768 } 01769 memset(vms->deleted, 0, arraysize * sizeof(int)); 01770 memset(vms->heard, 0, arraysize * sizeof(int)); 01771 vms->dh_arraysize = arraysize; 01772 } 01773 01774 return 0; 01775 }
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 9727 of file app_voicemail.c.
References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_test_suite_event_notify, ast_verb, ast_waitstream(), find_user(), ast_vm_user::password, S_COR, and vm_password.
Referenced by vm_execmain(), and vmauthenticate().
09730 { 09731 int useadsi = 0, valid = 0, logretries = 0; 09732 char password[AST_MAX_EXTENSION]="", *passptr; 09733 struct ast_vm_user vmus, *vmu = NULL; 09734 09735 /* If ADSI is supported, setup login screen */ 09736 adsi_begin(chan, &useadsi); 09737 if (!skipuser && useadsi) 09738 adsi_login(chan); 09739 ast_test_suite_event_notify("PLAYBACK", "Message: vm-login"); 09740 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09741 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09742 return -1; 09743 } 09744 09745 /* Authenticate them and get their mailbox/password */ 09746 09747 while (!valid && (logretries < max_logins)) { 09748 /* Prompt for, and read in the username */ 09749 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09750 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09751 return -1; 09752 } 09753 if (ast_strlen_zero(mailbox)) { 09754 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09755 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09756 } else { 09757 ast_verb(3, "Username not entered\n"); 09758 return -1; 09759 } 09760 } else if (mailbox[0] == '*') { 09761 /* user entered '*' */ 09762 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09763 if (ast_exists_extension(chan, chan->context, "a", 1, 09764 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09765 return -1; 09766 } 09767 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09768 mailbox[0] = '\0'; 09769 } 09770 09771 if (useadsi) 09772 adsi_password(chan); 09773 09774 if (!ast_strlen_zero(prefix)) { 09775 char fullusername[80] = ""; 09776 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09777 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09778 ast_copy_string(mailbox, fullusername, mailbox_size); 09779 } 09780 09781 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09782 vmu = find_user(&vmus, context, mailbox); 09783 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09784 /* saved password is blank, so don't bother asking */ 09785 password[0] = '\0'; 09786 } else { 09787 ast_test_suite_event_notify("PLAYBACK", "Message: %s", vm_password); 09788 if (ast_streamfile(chan, vm_password, chan->language)) { 09789 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09790 return -1; 09791 } 09792 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09793 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09794 return -1; 09795 } else if (password[0] == '*') { 09796 /* user entered '*' */ 09797 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09798 if (ast_exists_extension(chan, chan->context, "a", 1, 09799 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09800 mailbox[0] = '*'; 09801 return -1; 09802 } 09803 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09804 mailbox[0] = '\0'; 09805 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09806 vmu = NULL; 09807 } 09808 } 09809 09810 if (vmu) { 09811 passptr = vmu->password; 09812 if (passptr[0] == '-') passptr++; 09813 } 09814 if (vmu && !strcmp(passptr, password)) 09815 valid++; 09816 else { 09817 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09818 if (!ast_strlen_zero(prefix)) 09819 mailbox[0] = '\0'; 09820 } 09821 logretries++; 09822 if (!valid) { 09823 if (skipuser || logretries >= max_logins) { 09824 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect"); 09825 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09826 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09827 return -1; 09828 } 09829 } else { 09830 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect-mailbox"); 09831 if (useadsi) 09832 adsi_login(chan); 09833 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09834 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09835 return -1; 09836 } 09837 } 09838 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09839 return -1; 09840 } 09841 } 09842 if (!valid && (logretries >= max_logins)) { 09843 ast_stopstream(chan); 09844 ast_play_and_wait(chan, "vm-goodbye"); 09845 return -1; 09846 } 09847 if (vmu && !skipuser) { 09848 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09849 } 09850 return 0; 09851 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10960 of file app_voicemail.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_ERROR, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), find_user(), mbox(), and pbx_builtin_setvar_helper().
Referenced by load_module().
10961 { 10962 struct ast_vm_user svm; 10963 char *context, *box; 10964 AST_DECLARE_APP_ARGS(args, 10965 AST_APP_ARG(mbox); 10966 AST_APP_ARG(options); 10967 ); 10968 static int dep_warning = 0; 10969 10970 if (ast_strlen_zero(data)) { 10971 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 10972 return -1; 10973 } 10974 10975 if (!dep_warning) { 10976 dep_warning = 1; 10977 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 10978 } 10979 10980 box = ast_strdupa(data); 10981 10982 AST_STANDARD_APP_ARGS(args, box); 10983 10984 if (args.options) { 10985 } 10986 10987 if ((context = strchr(args.mbox, '@'))) { 10988 *context = '\0'; 10989 context++; 10990 } 10991 10992 if (find_user(&svm, context, args.mbox)) { 10993 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 10994 } else 10995 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 10996 10997 return 0; 10998 }
static int vm_browse_messages | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Top level method to invoke the language variant vm_browse_messages_XX function.
chan | The channel for the current user. We read the language property from this. | |
vms | passed into the language-specific vm_browse_messages function. | |
vmu | passed into the language-specific vm_browse_messages function. |
Definition at line 9706 of file app_voicemail.c.
References ast_channel::language, vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_browse_messages_vi(), and vm_browse_messages_zh().
Referenced by vm_execmain().
09707 { 09708 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09709 return vm_browse_messages_es(chan, vms, vmu); 09710 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09711 return vm_browse_messages_gr(chan, vms, vmu); 09712 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09713 return vm_browse_messages_he(chan, vms, vmu); 09714 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09715 return vm_browse_messages_it(chan, vms, vmu); 09716 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09717 return vm_browse_messages_pt(chan, vms, vmu); 09718 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09719 return vm_browse_messages_vi(chan, vms, vmu); 09720 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09721 return vm_browse_messages_zh(chan, vms, vmu); 09722 } else { /* Default to English syntax */ 09723 return vm_browse_messages_en(chan, vms, vmu); 09724 } 09725 }
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 9545 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().
09546 { 09547 int cmd = 0; 09548 09549 if (vms->lastmsg > -1) { 09550 cmd = play_message(chan, vmu, vms); 09551 } else { 09552 cmd = ast_play_and_wait(chan, "vm-youhave"); 09553 if (!cmd) 09554 cmd = ast_play_and_wait(chan, "vm-no"); 09555 if (!cmd) { 09556 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09557 cmd = ast_play_and_wait(chan, vms->fn); 09558 } 09559 if (!cmd) 09560 cmd = ast_play_and_wait(chan, "vm-messages"); 09561 } 09562 return cmd; 09563 }
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 9599 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().
09600 { 09601 int cmd; 09602 09603 if (vms->lastmsg > -1) { 09604 cmd = play_message(chan, vmu, vms); 09605 } else { 09606 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09607 if (!cmd) 09608 cmd = ast_play_and_wait(chan, "vm-messages"); 09609 if (!cmd) { 09610 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09611 cmd = ast_play_and_wait(chan, vms->fn); 09612 } 09613 } 09614 return cmd; 09615 }
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 9493 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().
09494 { 09495 int cmd = 0; 09496 09497 if (vms->lastmsg > -1) { 09498 cmd = play_message(chan, vmu, vms); 09499 } else { 09500 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09501 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09502 if (!cmd) { 09503 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09504 cmd = ast_play_and_wait(chan, vms->fn); 09505 } 09506 if (!cmd) 09507 cmd = ast_play_and_wait(chan, "vm-messages"); 09508 } else { 09509 if (!cmd) 09510 cmd = ast_play_and_wait(chan, "vm-messages"); 09511 if (!cmd) { 09512 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09513 cmd = ast_play_and_wait(chan, vms->fn); 09514 } 09515 } 09516 } 09517 return cmd; 09518 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9521 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09522 { 09523 int cmd = 0; 09524 09525 if (vms->lastmsg > -1) { 09526 cmd = play_message(chan, vmu, vms); 09527 } else { 09528 if (!strcasecmp(vms->fn, "INBOX")) { 09529 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09530 } else { 09531 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09532 } 09533 } 09534 return cmd; 09535 }
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 9573 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().
09574 { 09575 int cmd; 09576 09577 if (vms->lastmsg > -1) { 09578 cmd = play_message(chan, vmu, vms); 09579 } else { 09580 cmd = ast_play_and_wait(chan, "vm-no"); 09581 if (!cmd) 09582 cmd = ast_play_and_wait(chan, "vm-message"); 09583 if (!cmd) { 09584 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09585 cmd = ast_play_and_wait(chan, vms->fn); 09586 } 09587 } 09588 return cmd; 09589 }
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 9625 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().
09626 { 09627 int cmd; 09628 09629 if (vms->lastmsg > -1) { 09630 cmd = play_message(chan, vmu, vms); 09631 } else { 09632 cmd = ast_play_and_wait(chan, "vm-no"); 09633 if (!cmd) { 09634 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09635 cmd = ast_play_and_wait(chan, vms->fn); 09636 } 09637 if (!cmd) 09638 cmd = ast_play_and_wait(chan, "vm-messages"); 09639 } 09640 return cmd; 09641 }
static int vm_browse_messages_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Vietnamese syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9679 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().
09680 { 09681 int cmd = 0; 09682 09683 if (vms->lastmsg > -1) { 09684 cmd = play_message(chan, vmu, vms); 09685 } else { 09686 cmd = ast_play_and_wait(chan, "vm-no"); 09687 if (!cmd) { 09688 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09689 cmd = ast_play_and_wait(chan, vms->fn); 09690 } 09691 } 09692 return cmd; 09693 }
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 9651 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().
09652 { 09653 int cmd; 09654 09655 if (vms->lastmsg > -1) { 09656 cmd = play_message(chan, vmu, vms); 09657 } else { 09658 cmd = ast_play_and_wait(chan, "vm-you"); 09659 if (!cmd) 09660 cmd = ast_play_and_wait(chan, "vm-haveno"); 09661 if (!cmd) 09662 cmd = ast_play_and_wait(chan, "vm-messages"); 09663 if (!cmd) { 09664 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09665 cmd = ast_play_and_wait(chan, vms->fn); 09666 } 09667 } 09668 return cmd; 09669 }
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 1506 of file app_voicemail.c.
References ast_category_browse(), ast_category_get(), ast_config_load, ast_config_text_file_save(), ast_copy_string(), ast_debug, ast_free, ast_log(), AST_LOG_WARNING, ast_test_suite_event_notify, ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), ast_verb, change_password_realtime(), CONFIG_FLAG_WITHCOMMENTS, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::password, ast_vm_user::passwordlocation, reset_user_pw(), value, var, VM_SPOOL_DIR, VOICEMAIL_CONFIG, and write_password_to_file().
Referenced by vm_newuser(), and vm_options().
01507 { 01508 struct ast_config *cfg = NULL; 01509 struct ast_variable *var = NULL; 01510 struct ast_category *cat = NULL; 01511 char *category = NULL, *value = NULL, *new = NULL; 01512 const char *tmp = NULL; 01513 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01514 char secretfn[PATH_MAX] = ""; 01515 int found = 0; 01516 01517 if (!change_password_realtime(vmu, newpassword)) 01518 return; 01519 01520 /* check if we should store the secret in the spool directory next to the messages */ 01521 switch (vmu->passwordlocation) { 01522 case OPT_PWLOC_SPOOLDIR: 01523 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01524 if (write_password_to_file(secretfn, newpassword) == 0) { 01525 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf"); 01526 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01527 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01528 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01529 break; 01530 } else { 01531 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01532 } 01533 /* Fall-through */ 01534 case OPT_PWLOC_VOICEMAILCONF: 01535 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01536 while ((category = ast_category_browse(cfg, category))) { 01537 if (!strcasecmp(category, vmu->context)) { 01538 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01539 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01540 break; 01541 } 01542 value = strstr(tmp, ","); 01543 if (!value) { 01544 new = alloca(strlen(newpassword)+1); 01545 sprintf(new, "%s", newpassword); 01546 } else { 01547 new = alloca((strlen(value) + strlen(newpassword) + 1)); 01548 sprintf(new, "%s%s", newpassword, value); 01549 } 01550 if (!(cat = ast_category_get(cfg, category))) { 01551 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01552 break; 01553 } 01554 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01555 found = 1; 01556 } 01557 } 01558 /* save the results */ 01559 if (found) { 01560 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf"); 01561 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01562 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01563 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01564 break; 01565 } 01566 } 01567 /* Fall-through */ 01568 case OPT_PWLOC_USERSCONF: 01569 /* check users.conf and update the password stored for the mailbox */ 01570 /* if no vmsecret entry exists create one. */ 01571 if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01572 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01573 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01574 ast_debug(4, "users.conf: %s\n", category); 01575 if (!strcasecmp(category, vmu->mailbox)) { 01576 if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) { 01577 ast_debug(3, "looks like we need to make vmsecret!\n"); 01578 var = ast_variable_new("vmsecret", newpassword, ""); 01579 } else { 01580 var = NULL; 01581 } 01582 new = alloca(strlen(newpassword) + 1); 01583 sprintf(new, "%s", newpassword); 01584 if (!(cat = ast_category_get(cfg, category))) { 01585 ast_debug(4, "failed to get category!\n"); 01586 ast_free(var); 01587 break; 01588 } 01589 if (!var) { 01590 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01591 } else { 01592 ast_variable_append(cat, var); 01593 } 01594 found = 1; 01595 break; 01596 } 01597 } 01598 /* save the results and clean things up */ 01599 if (found) { 01600 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf"); 01601 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01602 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01603 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01604 } 01605 } 01606 } 01607 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1609 of file app_voicemail.c.
References ast_copy_string(), ast_debug, ast_safe_system(), ast_test_suite_event_notify, ast_vm_user::context, ext_pass_cmd, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().
Referenced by vm_newuser(), and vm_options().
01610 { 01611 char buf[255]; 01612 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01613 ast_debug(1, "External password: %s\n",buf); 01614 if (!ast_safe_system(buf)) { 01615 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external"); 01616 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01617 /* Reset the password in memory, too */ 01618 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01619 } 01620 }
static char* vm_check_password_shell | ( | char * | command, | |
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1181 of file app_voicemail.c.
References AST_APP_ARG, ast_close_fds_above_n(), AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_safe_fork(), ast_strdupa, errno, and LOG_WARNING.
Referenced by check_password().
01182 { 01183 int fds[2], pid = 0; 01184 01185 memset(buf, 0, len); 01186 01187 if (pipe(fds)) { 01188 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 01189 } else { 01190 /* good to go*/ 01191 pid = ast_safe_fork(0); 01192 01193 if (pid < 0) { 01194 /* ok maybe not */ 01195 close(fds[0]); 01196 close(fds[1]); 01197 snprintf(buf, len, "FAILURE: Fork failed"); 01198 } else if (pid) { 01199 /* parent */ 01200 close(fds[1]); 01201 if (read(fds[0], buf, len) < 0) { 01202 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 01203 } 01204 close(fds[0]); 01205 } else { 01206 /* child */ 01207 AST_DECLARE_APP_ARGS(arg, 01208 AST_APP_ARG(v)[20]; 01209 ); 01210 char *mycmd = ast_strdupa(command); 01211 01212 close(fds[0]); 01213 dup2(fds[1], STDOUT_FILENO); 01214 close(fds[1]); 01215 ast_close_fds_above_n(STDOUT_FILENO); 01216 01217 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 01218 01219 execv(arg.v[0], arg.v); 01220 printf("FAILURE: %s", strerror(errno)); 01221 _exit(0); 01222 } 01223 } 01224 return buf; 01225 }
static int vm_delete | ( | char * | file | ) | [static] |
Removes the voicemail sound and information file.
file | The path to the sound file. This will be the the folder and message index, without the extension. |
Definition at line 4179 of file app_voicemail.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
04180 { 04181 char *txt; 04182 int txtsize = 0; 04183 04184 txtsize = (strlen(file) + 5)*sizeof(char); 04185 txt = alloca(txtsize); 04186 /* Sprintf here would safe because we alloca'd exactly the right length, 04187 * but trying to eliminate all sprintf's anyhow 04188 */ 04189 if (ast_check_realtime("voicemail_data")) { 04190 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04191 } 04192 snprintf(txt, txtsize, "%s.txt", file); 04193 unlink(txt); 04194 return ast_filedelete(file, NULL); 04195 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10619 of file app_voicemail.c.
References ast_channel::_state, args, ast_answer(), AST_APP_ARG, ast_app_getdata(), ast_app_parse_options(), ast_copy_flags, AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_ERROR, ast_play_and_wait(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, ast_flags::flags, leave_voicemail(), OPERATOR_EXIT, OPT_ARG_ARRAY_SIZE, OPT_ARG_DTMFEXIT, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), and vm_app_options.
Referenced by load_module(), and play_record_review().
10620 { 10621 int res = 0; 10622 char *tmp; 10623 struct leave_vm_options leave_options; 10624 struct ast_flags flags = { 0 }; 10625 char *opts[OPT_ARG_ARRAY_SIZE]; 10626 AST_DECLARE_APP_ARGS(args, 10627 AST_APP_ARG(argv0); 10628 AST_APP_ARG(argv1); 10629 ); 10630 10631 memset(&leave_options, 0, sizeof(leave_options)); 10632 10633 if (chan->_state != AST_STATE_UP) 10634 ast_answer(chan); 10635 10636 if (!ast_strlen_zero(data)) { 10637 tmp = ast_strdupa(data); 10638 AST_STANDARD_APP_ARGS(args, tmp); 10639 if (args.argc == 2) { 10640 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10641 return -1; 10642 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10643 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10644 int gain; 10645 10646 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10647 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10648 return -1; 10649 } else { 10650 leave_options.record_gain = (signed char) gain; 10651 } 10652 } 10653 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10654 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10655 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10656 } 10657 } 10658 } else { 10659 char temp[256]; 10660 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10661 if (res < 0) 10662 return res; 10663 if (ast_strlen_zero(temp)) 10664 return 0; 10665 args.argv0 = ast_strdupa(temp); 10666 } 10667 10668 res = leave_voicemail(chan, args.argv0, &leave_options); 10669 if (res == 't') { 10670 ast_play_and_wait(chan, "vm-goodbye"); 10671 res = 0; 10672 } 10673 10674 if (res == OPERATOR_EXIT) { 10675 res = 0; 10676 } 10677 10678 if (res == ERROR_LOCK_PATH) { 10679 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10680 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10681 res = 0; 10682 } 10683 10684 return res; 10685 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9853 of file app_voicemail.c.
References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), advanced_options(), args, ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_inboxcount2(), ast_app_parse_options(), ast_calloc, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_free, ast_goto_if_exists(), ast_log(), AST_LOG_ERROR, ast_manager_event, ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_suite_assert, ast_test_suite_event_notify, ast_verb, ast_waitfordigit(), ast_vm_user::callback, close_mailbox(), ast_vm_user::context, ast_channel::context, dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), ast_flags::flags, forward_message(), free_user(), get_folder2(), get_folder_by_name(), globalflags, has_voicemail(), language, ast_vm_user::language, ast_vm_user::mailbox, make_file(), maxlogins, ast_vm_user::maxmsg, mbox(), NEW_FOLDER, OLD_FOLDER, open_mailbox(), OPERATOR_EXIT, OPT_ARG_ARRAY_SIZE, OPT_ARG_PLAYFOLDER, OPT_ARG_RECORDGAIN, OPT_AUTOPLAY, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, parse(), ast_vm_user::password, play_message(), queue_mwi_event(), run_externnotify(), save_to_folder(), say_and_wait(), 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 vmfmts.
Referenced by load_module().
09854 { 09855 /* XXX This is, admittedly, some pretty horrendous code. For some 09856 reason it just seemed a lot easier to do with GOTO's. I feel 09857 like I'm back in my GWBASIC days. XXX */ 09858 int res = -1; 09859 int cmd = 0; 09860 int valid = 0; 09861 char prefixstr[80] =""; 09862 char ext_context[256]=""; 09863 int box; 09864 int useadsi = 0; 09865 int skipuser = 0; 09866 struct vm_state vms; 09867 struct ast_vm_user *vmu = NULL, vmus; 09868 char *context = NULL; 09869 int silentexit = 0; 09870 struct ast_flags flags = { 0 }; 09871 signed char record_gain = 0; 09872 int play_auto = 0; 09873 int play_folder = 0; 09874 int in_urgent = 0; 09875 #ifdef IMAP_STORAGE 09876 int deleted = 0; 09877 #endif 09878 09879 /* Add the vm_state to the active list and keep it active */ 09880 memset(&vms, 0, sizeof(vms)); 09881 09882 vms.lastmsg = -1; 09883 09884 memset(&vmus, 0, sizeof(vmus)); 09885 09886 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09887 if (chan->_state != AST_STATE_UP) { 09888 ast_debug(1, "Before ast_answer\n"); 09889 ast_answer(chan); 09890 } 09891 09892 if (!ast_strlen_zero(data)) { 09893 char *opts[OPT_ARG_ARRAY_SIZE]; 09894 char *parse; 09895 AST_DECLARE_APP_ARGS(args, 09896 AST_APP_ARG(argv0); 09897 AST_APP_ARG(argv1); 09898 ); 09899 09900 parse = ast_strdupa(data); 09901 09902 AST_STANDARD_APP_ARGS(args, parse); 09903 09904 if (args.argc == 2) { 09905 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09906 return -1; 09907 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09908 int gain; 09909 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09910 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09911 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09912 return -1; 09913 } else { 09914 record_gain = (signed char) gain; 09915 } 09916 } else { 09917 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09918 } 09919 } 09920 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09921 play_auto = 1; 09922 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09923 /* See if it is a folder name first */ 09924 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09925 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09926 play_folder = -1; 09927 } 09928 } else { 09929 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09930 } 09931 } else { 09932 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09933 } 09934 if (play_folder > 9 || play_folder < 0) { 09935 ast_log(AST_LOG_WARNING, 09936 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09937 opts[OPT_ARG_PLAYFOLDER]); 09938 play_folder = 0; 09939 } 09940 } 09941 } else { 09942 /* old style options parsing */ 09943 while (*(args.argv0)) { 09944 if (*(args.argv0) == 's') 09945 ast_set_flag(&flags, OPT_SILENT); 09946 else if (*(args.argv0) == 'p') 09947 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 09948 else 09949 break; 09950 (args.argv0)++; 09951 } 09952 09953 } 09954 09955 valid = ast_test_flag(&flags, OPT_SILENT); 09956 09957 if ((context = strchr(args.argv0, '@'))) 09958 *context++ = '\0'; 09959 09960 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 09961 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 09962 else 09963 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 09964 09965 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 09966 skipuser++; 09967 else 09968 valid = 0; 09969 } 09970 09971 if (!valid) 09972 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 09973 09974 ast_debug(1, "After vm_authenticate\n"); 09975 09976 if (vms.username[0] == '*') { 09977 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 09978 09979 /* user entered '*' */ 09980 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 09981 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 09982 res = 0; /* prevent hangup */ 09983 goto out; 09984 } 09985 } 09986 09987 if (!res) { 09988 valid = 1; 09989 if (!skipuser) 09990 vmu = &vmus; 09991 } else { 09992 res = 0; 09993 } 09994 09995 /* If ADSI is supported, setup login screen */ 09996 adsi_begin(chan, &useadsi); 09997 09998 ast_test_suite_assert(valid); 09999 if (!valid) { 10000 goto out; 10001 } 10002 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10003 10004 #ifdef IMAP_STORAGE 10005 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10006 pthread_setspecific(ts_vmstate.key, &vms); 10007 10008 vms.interactive = 1; 10009 vms.updated = 1; 10010 if (vmu) 10011 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10012 vmstate_insert(&vms); 10013 init_vm_state(&vms); 10014 #endif 10015 /* Avoid allocating a buffer of 0 bytes, because some platforms really don't like that. */ 10016 if (!(vms.deleted = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 10017 ast_log(AST_LOG_ERROR, "Could not allocate memory for deleted message storage!\n"); 10018 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 10019 return -1; 10020 } 10021 if (!(vms.heard = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 10022 ast_log(AST_LOG_ERROR, "Could not allocate memory for heard message storage!\n"); 10023 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 10024 return -1; 10025 } 10026 10027 /* Set language from config to override channel language */ 10028 if (!ast_strlen_zero(vmu->language)) 10029 ast_string_field_set(chan, language, vmu->language); 10030 10031 /* Retrieve urgent, old and new message counts */ 10032 ast_debug(1, "Before open_mailbox\n"); 10033 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10034 if (res < 0) 10035 goto out; 10036 vms.oldmessages = vms.lastmsg + 1; 10037 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10038 /* check INBOX */ 10039 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10040 if (res < 0) 10041 goto out; 10042 vms.newmessages = vms.lastmsg + 1; 10043 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10044 /* Start in Urgent */ 10045 in_urgent = 1; 10046 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10047 if (res < 0) 10048 goto out; 10049 vms.urgentmessages = vms.lastmsg + 1; 10050 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10051 10052 /* Select proper mailbox FIRST!! */ 10053 if (play_auto) { 10054 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10055 if (vms.urgentmessages) { 10056 in_urgent = 1; 10057 res = open_mailbox(&vms, vmu, 11); 10058 } else { 10059 in_urgent = 0; 10060 res = open_mailbox(&vms, vmu, play_folder); 10061 } 10062 if (res < 0) 10063 goto out; 10064 10065 /* If there are no new messages, inform the user and hangup */ 10066 if (vms.lastmsg == -1) { 10067 in_urgent = 0; 10068 cmd = vm_browse_messages(chan, &vms, vmu); 10069 res = 0; 10070 goto out; 10071 } 10072 } else { 10073 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10074 /* If we only have old messages start here */ 10075 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10076 in_urgent = 0; 10077 play_folder = 1; 10078 if (res < 0) 10079 goto out; 10080 } else if (!vms.urgentmessages && vms.newmessages) { 10081 /* If we have new messages but none are urgent */ 10082 in_urgent = 0; 10083 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10084 if (res < 0) 10085 goto out; 10086 } 10087 } 10088 10089 if (useadsi) 10090 adsi_status(chan, &vms); 10091 res = 0; 10092 10093 /* Check to see if this is a new user */ 10094 if (!strcasecmp(vmu->mailbox, vmu->password) && 10095 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10096 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10097 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10098 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10099 if ((cmd == 't') || (cmd == '#')) { 10100 /* Timeout */ 10101 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10102 res = 0; 10103 goto out; 10104 } else if (cmd < 0) { 10105 /* Hangup */ 10106 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10107 res = -1; 10108 goto out; 10109 } 10110 } 10111 #ifdef IMAP_STORAGE 10112 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10113 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10114 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10115 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10116 } 10117 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10118 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10119 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10120 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10121 } 10122 #endif 10123 10124 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10125 if (play_auto) { 10126 cmd = '1'; 10127 } else { 10128 cmd = vm_intro(chan, vmu, &vms); 10129 } 10130 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10131 10132 vms.repeats = 0; 10133 vms.starting = 1; 10134 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10135 /* Run main menu */ 10136 switch (cmd) { 10137 case '1': /* First message */ 10138 vms.curmsg = 0; 10139 /* Fall through */ 10140 case '5': /* Play current message */ 10141 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10142 cmd = vm_browse_messages(chan, &vms, vmu); 10143 break; 10144 case '2': /* Change folders */ 10145 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10146 if (useadsi) 10147 adsi_folders(chan, 0, "Change to folder..."); 10148 10149 cmd = get_folder2(chan, "vm-changeto", 0); 10150 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10151 if (cmd == '#') { 10152 cmd = 0; 10153 } else if (cmd > 0) { 10154 cmd = cmd - '0'; 10155 res = close_mailbox(&vms, vmu); 10156 if (res == ERROR_LOCK_PATH) 10157 goto out; 10158 /* If folder is not urgent, set in_urgent to zero! */ 10159 if (cmd != 11) in_urgent = 0; 10160 res = open_mailbox(&vms, vmu, cmd); 10161 if (res < 0) 10162 goto out; 10163 play_folder = cmd; 10164 cmd = 0; 10165 } 10166 if (useadsi) 10167 adsi_status2(chan, &vms); 10168 10169 if (!cmd) { 10170 cmd = vm_play_folder_name(chan, vms.vmbox); 10171 } 10172 10173 vms.starting = 1; 10174 break; 10175 case '3': /* Advanced options */ 10176 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10177 cmd = 0; 10178 vms.repeats = 0; 10179 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10180 switch (cmd) { 10181 case '1': /* Reply */ 10182 if (vms.lastmsg > -1 && !vms.starting) { 10183 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10184 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10185 res = cmd; 10186 goto out; 10187 } 10188 } else { 10189 cmd = ast_play_and_wait(chan, "vm-sorry"); 10190 } 10191 cmd = 't'; 10192 break; 10193 case '2': /* Callback */ 10194 if (!vms.starting) 10195 ast_verb(3, "Callback Requested\n"); 10196 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10197 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10198 if (cmd == 9) { 10199 silentexit = 1; 10200 goto out; 10201 } else if (cmd == ERROR_LOCK_PATH) { 10202 res = cmd; 10203 goto out; 10204 } 10205 } else { 10206 cmd = ast_play_and_wait(chan, "vm-sorry"); 10207 } 10208 cmd = 't'; 10209 break; 10210 case '3': /* Envelope */ 10211 if (vms.lastmsg > -1 && !vms.starting) { 10212 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10213 if (cmd == ERROR_LOCK_PATH) { 10214 res = cmd; 10215 goto out; 10216 } 10217 } else { 10218 cmd = ast_play_and_wait(chan, "vm-sorry"); 10219 } 10220 cmd = 't'; 10221 break; 10222 case '4': /* Dialout */ 10223 if (!ast_strlen_zero(vmu->dialout)) { 10224 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10225 if (cmd == 9) { 10226 silentexit = 1; 10227 goto out; 10228 } 10229 } else { 10230 cmd = ast_play_and_wait(chan, "vm-sorry"); 10231 } 10232 cmd = 't'; 10233 break; 10234 10235 case '5': /* Leave VoiceMail */ 10236 if (ast_test_flag(vmu, VM_SVMAIL)) { 10237 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10238 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10239 res = cmd; 10240 goto out; 10241 } 10242 } else { 10243 cmd = ast_play_and_wait(chan, "vm-sorry"); 10244 } 10245 cmd = 't'; 10246 break; 10247 10248 case '*': /* Return to main menu */ 10249 cmd = 't'; 10250 break; 10251 10252 default: 10253 cmd = 0; 10254 if (!vms.starting) { 10255 cmd = ast_play_and_wait(chan, "vm-toreply"); 10256 } 10257 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10258 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10259 } 10260 if (!cmd && !vms.starting) { 10261 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10262 } 10263 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10264 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10265 } 10266 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10267 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10268 } 10269 if (!cmd) { 10270 cmd = ast_play_and_wait(chan, "vm-starmain"); 10271 } 10272 if (!cmd) { 10273 cmd = ast_waitfordigit(chan, 6000); 10274 } 10275 if (!cmd) { 10276 vms.repeats++; 10277 } 10278 if (vms.repeats > 3) { 10279 cmd = 't'; 10280 } 10281 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10282 } 10283 } 10284 if (cmd == 't') { 10285 cmd = 0; 10286 vms.repeats = 0; 10287 } 10288 break; 10289 case '4': /* Go to the previous message */ 10290 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10291 if (vms.curmsg > 0) { 10292 vms.curmsg--; 10293 cmd = play_message(chan, vmu, &vms); 10294 } else { 10295 /* Check if we were listening to new 10296 messages. If so, go to Urgent messages 10297 instead of saying "no more messages" 10298 */ 10299 if (in_urgent == 0 && vms.urgentmessages > 0) { 10300 /* Check for Urgent messages */ 10301 in_urgent = 1; 10302 res = close_mailbox(&vms, vmu); 10303 if (res == ERROR_LOCK_PATH) 10304 goto out; 10305 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10306 if (res < 0) 10307 goto out; 10308 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10309 vms.curmsg = vms.lastmsg; 10310 if (vms.lastmsg < 0) { 10311 cmd = ast_play_and_wait(chan, "vm-nomore"); 10312 } 10313 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10314 vms.curmsg = vms.lastmsg; 10315 cmd = play_message(chan, vmu, &vms); 10316 } else { 10317 cmd = ast_play_and_wait(chan, "vm-nomore"); 10318 } 10319 } 10320 break; 10321 case '6': /* Go to the next message */ 10322 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10323 if (vms.curmsg < vms.lastmsg) { 10324 vms.curmsg++; 10325 cmd = play_message(chan, vmu, &vms); 10326 } else { 10327 if (in_urgent && vms.newmessages > 0) { 10328 /* Check if we were listening to urgent 10329 * messages. If so, go to regular new messages 10330 * instead of saying "no more messages" 10331 */ 10332 in_urgent = 0; 10333 res = close_mailbox(&vms, vmu); 10334 if (res == ERROR_LOCK_PATH) 10335 goto out; 10336 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10337 if (res < 0) 10338 goto out; 10339 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10340 vms.curmsg = -1; 10341 if (vms.lastmsg < 0) { 10342 cmd = ast_play_and_wait(chan, "vm-nomore"); 10343 } 10344 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10345 vms.curmsg = 0; 10346 cmd = play_message(chan, vmu, &vms); 10347 } else { 10348 cmd = ast_play_and_wait(chan, "vm-nomore"); 10349 } 10350 } 10351 break; 10352 case '7': /* Delete the current message */ 10353 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10354 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10355 if (useadsi) 10356 adsi_delete(chan, &vms); 10357 if (vms.deleted[vms.curmsg]) { 10358 if (play_folder == 0) { 10359 if (in_urgent) { 10360 vms.urgentmessages--; 10361 } else { 10362 vms.newmessages--; 10363 } 10364 } 10365 else if (play_folder == 1) 10366 vms.oldmessages--; 10367 cmd = ast_play_and_wait(chan, "vm-deleted"); 10368 } else { 10369 if (play_folder == 0) { 10370 if (in_urgent) { 10371 vms.urgentmessages++; 10372 } else { 10373 vms.newmessages++; 10374 } 10375 } 10376 else if (play_folder == 1) 10377 vms.oldmessages++; 10378 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10379 } 10380 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10381 if (vms.curmsg < vms.lastmsg) { 10382 vms.curmsg++; 10383 cmd = play_message(chan, vmu, &vms); 10384 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10385 vms.curmsg = 0; 10386 cmd = play_message(chan, vmu, &vms); 10387 } else { 10388 /* Check if we were listening to urgent 10389 messages. If so, go to regular new messages 10390 instead of saying "no more messages" 10391 */ 10392 if (in_urgent == 1) { 10393 /* Check for new messages */ 10394 in_urgent = 0; 10395 res = close_mailbox(&vms, vmu); 10396 if (res == ERROR_LOCK_PATH) 10397 goto out; 10398 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10399 if (res < 0) 10400 goto out; 10401 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10402 vms.curmsg = -1; 10403 if (vms.lastmsg < 0) { 10404 cmd = ast_play_and_wait(chan, "vm-nomore"); 10405 } 10406 } else { 10407 cmd = ast_play_and_wait(chan, "vm-nomore"); 10408 } 10409 } 10410 } 10411 } else /* Delete not valid if we haven't selected a message */ 10412 cmd = 0; 10413 #ifdef IMAP_STORAGE 10414 deleted = 1; 10415 #endif 10416 break; 10417 10418 case '8': /* Forward the current message */ 10419 if (vms.lastmsg > -1) { 10420 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10421 if (cmd == ERROR_LOCK_PATH) { 10422 res = cmd; 10423 goto out; 10424 } 10425 } else { 10426 /* Check if we were listening to urgent 10427 messages. If so, go to regular new messages 10428 instead of saying "no more messages" 10429 */ 10430 if (in_urgent == 1 && vms.newmessages > 0) { 10431 /* Check for new messages */ 10432 in_urgent = 0; 10433 res = close_mailbox(&vms, vmu); 10434 if (res == ERROR_LOCK_PATH) 10435 goto out; 10436 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10437 if (res < 0) 10438 goto out; 10439 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10440 vms.curmsg = -1; 10441 if (vms.lastmsg < 0) { 10442 cmd = ast_play_and_wait(chan, "vm-nomore"); 10443 } 10444 } else { 10445 cmd = ast_play_and_wait(chan, "vm-nomore"); 10446 } 10447 } 10448 break; 10449 case '9': /* Save message to folder */ 10450 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10451 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10452 /* No message selected */ 10453 cmd = 0; 10454 break; 10455 } 10456 if (useadsi) 10457 adsi_folders(chan, 1, "Save to folder..."); 10458 cmd = get_folder2(chan, "vm-savefolder", 1); 10459 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10460 box = 0; /* Shut up compiler */ 10461 if (cmd == '#') { 10462 cmd = 0; 10463 break; 10464 } else if (cmd > 0) { 10465 box = cmd = cmd - '0'; 10466 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10467 if (cmd == ERROR_LOCK_PATH) { 10468 res = cmd; 10469 goto out; 10470 #ifndef IMAP_STORAGE 10471 } else if (!cmd) { 10472 vms.deleted[vms.curmsg] = 1; 10473 #endif 10474 } else { 10475 vms.deleted[vms.curmsg] = 0; 10476 vms.heard[vms.curmsg] = 0; 10477 } 10478 } 10479 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10480 if (useadsi) 10481 adsi_message(chan, &vms); 10482 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10483 if (!cmd) { 10484 cmd = ast_play_and_wait(chan, "vm-message"); 10485 if (!cmd) 10486 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10487 if (!cmd) 10488 cmd = ast_play_and_wait(chan, "vm-savedto"); 10489 if (!cmd) 10490 cmd = vm_play_folder_name(chan, vms.fn); 10491 } else { 10492 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10493 } 10494 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10495 if (vms.curmsg < vms.lastmsg) { 10496 vms.curmsg++; 10497 cmd = play_message(chan, vmu, &vms); 10498 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10499 vms.curmsg = 0; 10500 cmd = play_message(chan, vmu, &vms); 10501 } else { 10502 /* Check if we were listening to urgent 10503 messages. If so, go to regular new messages 10504 instead of saying "no more messages" 10505 */ 10506 if (in_urgent == 1 && vms.newmessages > 0) { 10507 /* Check for new messages */ 10508 in_urgent = 0; 10509 res = close_mailbox(&vms, vmu); 10510 if (res == ERROR_LOCK_PATH) 10511 goto out; 10512 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10513 if (res < 0) 10514 goto out; 10515 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10516 vms.curmsg = -1; 10517 if (vms.lastmsg < 0) { 10518 cmd = ast_play_and_wait(chan, "vm-nomore"); 10519 } 10520 } else { 10521 cmd = ast_play_and_wait(chan, "vm-nomore"); 10522 } 10523 } 10524 } 10525 break; 10526 case '*': /* Help */ 10527 if (!vms.starting) { 10528 cmd = ast_play_and_wait(chan, "vm-onefor"); 10529 if (!strncasecmp(chan->language, "he", 2)) { 10530 cmd = ast_play_and_wait(chan, "vm-for"); 10531 } 10532 if (!cmd) 10533 cmd = vm_play_folder_name(chan, vms.vmbox); 10534 if (!cmd) 10535 cmd = ast_play_and_wait(chan, "vm-opts"); 10536 if (!cmd) 10537 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10538 } else 10539 cmd = 0; 10540 break; 10541 case '0': /* Mailbox options */ 10542 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10543 if (useadsi) 10544 adsi_status(chan, &vms); 10545 break; 10546 default: /* Nothing */ 10547 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10548 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10549 break; 10550 } 10551 } 10552 if ((cmd == 't') || (cmd == '#')) { 10553 /* Timeout */ 10554 res = 0; 10555 } else { 10556 /* Hangup */ 10557 res = -1; 10558 } 10559 10560 out: 10561 if (res > -1) { 10562 ast_stopstream(chan); 10563 adsi_goodbye(chan); 10564 if (valid && res != OPERATOR_EXIT) { 10565 if (silentexit) 10566 res = ast_play_and_wait(chan, "vm-dialout"); 10567 else 10568 res = ast_play_and_wait(chan, "vm-goodbye"); 10569 } 10570 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10571 res = 0; 10572 } 10573 if (useadsi) 10574 ast_adsi_unload_session(chan); 10575 } 10576 if (vmu) 10577 close_mailbox(&vms, vmu); 10578 if (valid) { 10579 int new = 0, old = 0, urgent = 0; 10580 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10581 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10582 /* Urgent flag not passwd to externnotify here */ 10583 run_externnotify(vmu->context, vmu->mailbox, NULL); 10584 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10585 queue_mwi_event(ext_context, urgent, new, old); 10586 } 10587 #ifdef IMAP_STORAGE 10588 /* expunge message - use UID Expunge if supported on IMAP server*/ 10589 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10590 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10591 ast_mutex_lock(&vms.lock); 10592 #ifdef HAVE_IMAP_TK2006 10593 if (LEVELUIDPLUS (vms.mailstream)) { 10594 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10595 } else 10596 #endif 10597 mail_expunge(vms.mailstream); 10598 ast_mutex_unlock(&vms.lock); 10599 } 10600 /* before we delete the state, we should copy pertinent info 10601 * back to the persistent model */ 10602 if (vmu) { 10603 vmstate_delete(&vms); 10604 } 10605 #endif 10606 if (vmu) 10607 free_user(vmu); 10608 if (vms.deleted) 10609 ast_free(vms.deleted); 10610 if (vms.heard) 10611 ast_free(vms.heard); 10612 10613 #ifdef IMAP_STORAGE 10614 pthread_setspecific(ts_vmstate.key, NULL); 10615 #endif 10616 return res; 10617 }
static int vm_forwardoptions | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | curdir, | |||
int | curmsg, | |||
char * | vm_fmts, | |||
char * | context, | |||
signed char | record_gain, | |||
long * | duration, | |||
struct vm_state * | vms, | |||
char * | flag | |||
) | [static] |
presents the option to prepend to an existing message when forwarding it.
chan | ||
vmu | ||
curdir | ||
curmsg | ||
vm_fmts | ||
context | ||
record_gain | ||
duration | ||
vms | ||
flag |
This is invoked from forward_message() when performing a forward operation (option 8 from main menu).
Definition at line 6842 of file app_voicemail.c.
References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load, ast_config_text_file_save(), ast_filecopy(), ast_filerename(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_stream_and_wait(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, copy(), INTRO, make_file(), ast_vm_user::maxsecs, maxsilence, play_record_review(), silencethreshold, vm_pls_try_again, and vm_prepend_timeout.
Referenced by forward_message().
06844 { 06845 int cmd = 0; 06846 int retries = 0, prepend_duration = 0, already_recorded = 0; 06847 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06848 char textfile[PATH_MAX]; 06849 struct ast_config *msg_cfg; 06850 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06851 #ifndef IMAP_STORAGE 06852 signed char zero_gain = 0; 06853 #endif 06854 const char *duration_str; 06855 06856 /* Must always populate duration correctly */ 06857 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06858 strcpy(textfile, msgfile); 06859 strcpy(backup, msgfile); 06860 strcpy(backup_textfile, msgfile); 06861 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06862 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06863 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06864 06865 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06866 *duration = atoi(duration_str); 06867 } else { 06868 *duration = 0; 06869 } 06870 06871 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06872 if (cmd) 06873 retries = 0; 06874 switch (cmd) { 06875 case '1': 06876 06877 #ifdef IMAP_STORAGE 06878 /* Record new intro file */ 06879 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06880 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06881 ast_play_and_wait(chan, INTRO); 06882 ast_play_and_wait(chan, "beep"); 06883 play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06884 cmd = 't'; 06885 #else 06886 06887 /* prepend a message to the current message, update the metadata and return */ 06888 06889 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06890 strcpy(textfile, msgfile); 06891 strncat(textfile, ".txt", sizeof(textfile) - 1); 06892 *duration = 0; 06893 06894 /* if we can't read the message metadata, stop now */ 06895 if (!msg_cfg) { 06896 cmd = 0; 06897 break; 06898 } 06899 06900 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06901 #ifndef IMAP_STORAGE 06902 if (already_recorded) { 06903 ast_filecopy(backup, msgfile, NULL); 06904 copy(backup_textfile, textfile); 06905 } 06906 else { 06907 ast_filecopy(msgfile, backup, NULL); 06908 copy(textfile, backup_textfile); 06909 } 06910 #endif 06911 already_recorded = 1; 06912 06913 if (record_gain) 06914 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06915 06916 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 06917 06918 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 06919 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 06920 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 06921 ast_filerename(backup, msgfile, NULL); 06922 } 06923 06924 if (record_gain) 06925 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06926 06927 06928 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06929 *duration = atoi(duration_str); 06930 06931 if (prepend_duration) { 06932 struct ast_category *msg_cat; 06933 /* need enough space for a maximum-length message duration */ 06934 char duration_buf[12]; 06935 06936 *duration += prepend_duration; 06937 msg_cat = ast_category_get(msg_cfg, "message"); 06938 snprintf(duration_buf, 11, "%ld", *duration); 06939 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06940 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06941 } 06942 } 06943 06944 #endif 06945 break; 06946 case '2': 06947 /* NULL out introfile so we know there is no intro! */ 06948 #ifdef IMAP_STORAGE 06949 *vms->introfn = '\0'; 06950 #endif 06951 cmd = 't'; 06952 break; 06953 case '*': 06954 cmd = '*'; 06955 break; 06956 default: 06957 /* If time_out and return to menu, reset already_recorded */ 06958 already_recorded = 0; 06959 06960 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 06961 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06962 if (!cmd) { 06963 cmd = ast_play_and_wait(chan, "vm-starmain"); 06964 /* "press star to return to the main menu" */ 06965 } 06966 if (!cmd) { 06967 cmd = ast_waitfordigit(chan, 6000); 06968 } 06969 if (!cmd) { 06970 retries++; 06971 } 06972 if (retries > 3) { 06973 cmd = '*'; /* Let's cancel this beast */ 06974 } 06975 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 06976 } 06977 } 06978 06979 if (msg_cfg) 06980 ast_config_destroy(msg_cfg); 06981 if (prepend_duration) 06982 *duration = prepend_duration; 06983 06984 if (already_recorded && cmd == -1) { 06985 /* restore original message if prepention cancelled */ 06986 ast_filerename(backup, msgfile, NULL); 06987 rename(backup_textfile, textfile); 06988 } 06989 06990 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 06991 cmd = 0; 06992 return cmd; 06993 }
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 9171 of file app_voicemail.c.
References ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
09172 { 09173 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09174 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09175 } else { /* Default to ENGLISH */ 09176 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09177 } 09178 }
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 9070 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().
09071 { 09072 int res = 0; 09073 /* Play instructions and wait for new command */ 09074 while (!res) { 09075 if (vms->starting) { 09076 if (vms->lastmsg > -1) { 09077 if (skipadvanced) 09078 res = ast_play_and_wait(chan, "vm-onefor-full"); 09079 else 09080 res = ast_play_and_wait(chan, "vm-onefor"); 09081 if (!res) 09082 res = vm_play_folder_name(chan, vms->vmbox); 09083 } 09084 if (!res) { 09085 if (skipadvanced) 09086 res = ast_play_and_wait(chan, "vm-opts-full"); 09087 else 09088 res = ast_play_and_wait(chan, "vm-opts"); 09089 } 09090 } else { 09091 /* Added for additional help */ 09092 if (skipadvanced) { 09093 res = ast_play_and_wait(chan, "vm-onefor-full"); 09094 if (!res) 09095 res = vm_play_folder_name(chan, vms->vmbox); 09096 res = ast_play_and_wait(chan, "vm-opts-full"); 09097 } 09098 /* Logic: 09099 * If the current message is not the first OR 09100 * if we're listening to the first new message and there are 09101 * also urgent messages, then prompt for navigation to the 09102 * previous message 09103 */ 09104 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09105 res = ast_play_and_wait(chan, "vm-prev"); 09106 } 09107 if (!res && !skipadvanced) 09108 res = ast_play_and_wait(chan, "vm-advopts"); 09109 if (!res) 09110 res = ast_play_and_wait(chan, "vm-repeat"); 09111 /* Logic: 09112 * If we're not listening to the last message OR 09113 * we're listening to the last urgent message and there are 09114 * also new non-urgent messages, then prompt for navigation 09115 * to the next message 09116 */ 09117 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09118 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09119 res = ast_play_and_wait(chan, "vm-next"); 09120 } 09121 if (!res) { 09122 if (!vms->deleted[vms->curmsg]) 09123 res = ast_play_and_wait(chan, "vm-delete"); 09124 else 09125 res = ast_play_and_wait(chan, "vm-undelete"); 09126 if (!res) 09127 res = ast_play_and_wait(chan, "vm-toforward"); 09128 if (!res) 09129 res = ast_play_and_wait(chan, "vm-savemessage"); 09130 } 09131 } 09132 if (!res) { 09133 res = ast_play_and_wait(chan, "vm-helpexit"); 09134 } 09135 if (!res) 09136 res = ast_waitfordigit(chan, 6000); 09137 if (!res) { 09138 vms->repeats++; 09139 if (vms->repeats > 2) { 09140 res = 't'; 09141 } 09142 } 09143 } 09144 return res; 09145 }
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 9147 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().
09148 { 09149 int res = 0; 09150 /* Play instructions and wait for new command */ 09151 while (!res) { 09152 if (vms->lastmsg > -1) { 09153 res = ast_play_and_wait(chan, "vm-listen"); 09154 if (!res) 09155 res = vm_play_folder_name(chan, vms->vmbox); 09156 if (!res) 09157 res = ast_play_and_wait(chan, "press"); 09158 if (!res) 09159 res = ast_play_and_wait(chan, "digits/1"); 09160 } 09161 if (!res) 09162 res = ast_play_and_wait(chan, "vm-opts"); 09163 if (!res) { 09164 vms->starting = 0; 09165 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09166 } 09167 } 09168 return res; 09169 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 9008 of file app_voicemail.c.
References ast_fileexists(), ast_log(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, DISPOSE, ast_channel::language, LOG_WARNING, ast_vm_user::mailbox, RETRIEVE, vm_state::username, vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_he(), vm_intro_it(), vm_intro_multilang(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_se(), vm_intro_vi(), vm_intro_zh(), VM_SPOOL_DIR, and VM_TEMPGREETWARN.
Referenced by vm_execmain().
09009 { 09010 char prefile[256]; 09011 09012 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09013 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09014 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09015 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09016 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09017 ast_play_and_wait(chan, "vm-tempgreetactive"); 09018 } 09019 DISPOSE(prefile, -1); 09020 } 09021 09022 /* Play voicemail intro - syntax is different for different languages */ 09023 if (0) { 09024 return 0; 09025 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09026 return vm_intro_cs(chan, vms); 09027 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09028 static int deprecation_warning = 0; 09029 if (deprecation_warning++ % 10 == 0) { 09030 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09031 } 09032 return vm_intro_cs(chan, vms); 09033 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09034 return vm_intro_de(chan, vms); 09035 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09036 return vm_intro_es(chan, vms); 09037 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09038 return vm_intro_fr(chan, vms); 09039 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09040 return vm_intro_gr(chan, vms); 09041 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09042 return vm_intro_he(chan, vms); 09043 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09044 return vm_intro_it(chan, vms); 09045 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09046 return vm_intro_nl(chan, vms); 09047 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09048 return vm_intro_no(chan, vms); 09049 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09050 return vm_intro_pl(chan, vms); 09051 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09052 return vm_intro_pt_BR(chan, vms); 09053 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09054 return vm_intro_pt(chan, vms); 09055 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09056 return vm_intro_multilang(chan, vms, "n"); 09057 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09058 return vm_intro_se(chan, vms); 09059 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09060 return vm_intro_multilang(chan, vms, "n"); 09061 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09062 return vm_intro_vi(chan, vms); 09063 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09064 return vm_intro_zh(chan, vms); 09065 } else { /* Default to ENGLISH */ 09066 return vm_intro_en(chan, vms); 09067 } 09068 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8878 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08879 { 08880 int res; 08881 res = ast_play_and_wait(chan, "vm-youhave"); 08882 if (!res) { 08883 if (vms->newmessages) { 08884 if (vms->newmessages == 1) { 08885 res = ast_play_and_wait(chan, "digits/jednu"); 08886 } else { 08887 res = say_and_wait(chan, vms->newmessages, chan->language); 08888 } 08889 if (!res) { 08890 if ((vms->newmessages == 1)) 08891 res = ast_play_and_wait(chan, "vm-novou"); 08892 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08893 res = ast_play_and_wait(chan, "vm-nove"); 08894 if (vms->newmessages > 4) 08895 res = ast_play_and_wait(chan, "vm-novych"); 08896 } 08897 if (vms->oldmessages && !res) 08898 res = ast_play_and_wait(chan, "vm-and"); 08899 else if (!res) { 08900 if ((vms->newmessages == 1)) 08901 res = ast_play_and_wait(chan, "vm-zpravu"); 08902 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08903 res = ast_play_and_wait(chan, "vm-zpravy"); 08904 if (vms->newmessages > 4) 08905 res = ast_play_and_wait(chan, "vm-zprav"); 08906 } 08907 } 08908 if (!res && vms->oldmessages) { 08909 res = say_and_wait(chan, vms->oldmessages, chan->language); 08910 if (!res) { 08911 if ((vms->oldmessages == 1)) 08912 res = ast_play_and_wait(chan, "vm-starou"); 08913 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08914 res = ast_play_and_wait(chan, "vm-stare"); 08915 if (vms->oldmessages > 4) 08916 res = ast_play_and_wait(chan, "vm-starych"); 08917 } 08918 if (!res) { 08919 if ((vms->oldmessages == 1)) 08920 res = ast_play_and_wait(chan, "vm-zpravu"); 08921 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08922 res = ast_play_and_wait(chan, "vm-zpravy"); 08923 if (vms->oldmessages > 4) 08924 res = ast_play_and_wait(chan, "vm-zprav"); 08925 } 08926 } 08927 if (!res) { 08928 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08929 res = ast_play_and_wait(chan, "vm-no"); 08930 if (!res) 08931 res = ast_play_and_wait(chan, "vm-zpravy"); 08932 } 08933 } 08934 } 08935 return res; 08936 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8574 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08575 { 08576 /* Introduce messages they have */ 08577 int res; 08578 res = ast_play_and_wait(chan, "vm-youhave"); 08579 if (!res) { 08580 if (vms->newmessages) { 08581 if ((vms->newmessages == 1)) 08582 res = ast_play_and_wait(chan, "digits/1F"); 08583 else 08584 res = say_and_wait(chan, vms->newmessages, chan->language); 08585 if (!res) 08586 res = ast_play_and_wait(chan, "vm-INBOX"); 08587 if (vms->oldmessages && !res) 08588 res = ast_play_and_wait(chan, "vm-and"); 08589 else if (!res) { 08590 if ((vms->newmessages == 1)) 08591 res = ast_play_and_wait(chan, "vm-message"); 08592 else 08593 res = ast_play_and_wait(chan, "vm-messages"); 08594 } 08595 08596 } 08597 if (!res && vms->oldmessages) { 08598 if (vms->oldmessages == 1) 08599 res = ast_play_and_wait(chan, "digits/1F"); 08600 else 08601 res = say_and_wait(chan, vms->oldmessages, chan->language); 08602 if (!res) 08603 res = ast_play_and_wait(chan, "vm-Old"); 08604 if (!res) { 08605 if (vms->oldmessages == 1) 08606 res = ast_play_and_wait(chan, "vm-message"); 08607 else 08608 res = ast_play_and_wait(chan, "vm-messages"); 08609 } 08610 } 08611 if (!res) { 08612 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08613 res = ast_play_and_wait(chan, "vm-no"); 08614 if (!res) 08615 res = ast_play_and_wait(chan, "vm-messages"); 08616 } 08617 } 08618 } 08619 return res; 08620 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8323 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08324 { 08325 int res; 08326 08327 /* Introduce messages they have */ 08328 res = ast_play_and_wait(chan, "vm-youhave"); 08329 if (!res) { 08330 if (vms->urgentmessages) { 08331 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08332 if (!res) 08333 res = ast_play_and_wait(chan, "vm-Urgent"); 08334 if ((vms->oldmessages || vms->newmessages) && !res) { 08335 res = ast_play_and_wait(chan, "vm-and"); 08336 } else if (!res) { 08337 if ((vms->urgentmessages == 1)) 08338 res = ast_play_and_wait(chan, "vm-message"); 08339 else 08340 res = ast_play_and_wait(chan, "vm-messages"); 08341 } 08342 } 08343 if (vms->newmessages) { 08344 res = say_and_wait(chan, vms->newmessages, chan->language); 08345 if (!res) 08346 res = ast_play_and_wait(chan, "vm-INBOX"); 08347 if (vms->oldmessages && !res) 08348 res = ast_play_and_wait(chan, "vm-and"); 08349 else if (!res) { 08350 if ((vms->newmessages == 1)) 08351 res = ast_play_and_wait(chan, "vm-message"); 08352 else 08353 res = ast_play_and_wait(chan, "vm-messages"); 08354 } 08355 08356 } 08357 if (!res && vms->oldmessages) { 08358 res = say_and_wait(chan, vms->oldmessages, chan->language); 08359 if (!res) 08360 res = ast_play_and_wait(chan, "vm-Old"); 08361 if (!res) { 08362 if (vms->oldmessages == 1) 08363 res = ast_play_and_wait(chan, "vm-message"); 08364 else 08365 res = ast_play_and_wait(chan, "vm-messages"); 08366 } 08367 } 08368 if (!res) { 08369 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08370 res = ast_play_and_wait(chan, "vm-no"); 08371 if (!res) 08372 res = ast_play_and_wait(chan, "vm-messages"); 08373 } 08374 } 08375 } 08376 return res; 08377 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8623 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08624 { 08625 /* Introduce messages they have */ 08626 int res; 08627 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08628 res = ast_play_and_wait(chan, "vm-youhaveno"); 08629 if (!res) 08630 res = ast_play_and_wait(chan, "vm-messages"); 08631 } else { 08632 res = ast_play_and_wait(chan, "vm-youhave"); 08633 } 08634 if (!res) { 08635 if (vms->newmessages) { 08636 if (!res) { 08637 if ((vms->newmessages == 1)) { 08638 res = ast_play_and_wait(chan, "digits/1M"); 08639 if (!res) 08640 res = ast_play_and_wait(chan, "vm-message"); 08641 if (!res) 08642 res = ast_play_and_wait(chan, "vm-INBOXs"); 08643 } else { 08644 res = say_and_wait(chan, vms->newmessages, chan->language); 08645 if (!res) 08646 res = ast_play_and_wait(chan, "vm-messages"); 08647 if (!res) 08648 res = ast_play_and_wait(chan, "vm-INBOX"); 08649 } 08650 } 08651 if (vms->oldmessages && !res) 08652 res = ast_play_and_wait(chan, "vm-and"); 08653 } 08654 if (vms->oldmessages) { 08655 if (!res) { 08656 if (vms->oldmessages == 1) { 08657 res = ast_play_and_wait(chan, "digits/1M"); 08658 if (!res) 08659 res = ast_play_and_wait(chan, "vm-message"); 08660 if (!res) 08661 res = ast_play_and_wait(chan, "vm-Olds"); 08662 } else { 08663 res = say_and_wait(chan, vms->oldmessages, chan->language); 08664 if (!res) 08665 res = ast_play_and_wait(chan, "vm-messages"); 08666 if (!res) 08667 res = ast_play_and_wait(chan, "vm-Old"); 08668 } 08669 } 08670 } 08671 } 08672 return res; 08673 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8721 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08722 { 08723 /* Introduce messages they have */ 08724 int res; 08725 res = ast_play_and_wait(chan, "vm-youhave"); 08726 if (!res) { 08727 if (vms->newmessages) { 08728 res = say_and_wait(chan, vms->newmessages, chan->language); 08729 if (!res) 08730 res = ast_play_and_wait(chan, "vm-INBOX"); 08731 if (vms->oldmessages && !res) 08732 res = ast_play_and_wait(chan, "vm-and"); 08733 else if (!res) { 08734 if ((vms->newmessages == 1)) 08735 res = ast_play_and_wait(chan, "vm-message"); 08736 else 08737 res = ast_play_and_wait(chan, "vm-messages"); 08738 } 08739 08740 } 08741 if (!res && vms->oldmessages) { 08742 res = say_and_wait(chan, vms->oldmessages, chan->language); 08743 if (!res) 08744 res = ast_play_and_wait(chan, "vm-Old"); 08745 if (!res) { 08746 if (vms->oldmessages == 1) 08747 res = ast_play_and_wait(chan, "vm-message"); 08748 else 08749 res = ast_play_and_wait(chan, "vm-messages"); 08750 } 08751 } 08752 if (!res) { 08753 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08754 res = ast_play_and_wait(chan, "vm-no"); 08755 if (!res) 08756 res = ast_play_and_wait(chan, "vm-messages"); 08757 } 08758 } 08759 } 08760 return res; 08761 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8122 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08123 { 08124 int res = 0; 08125 08126 if (vms->newmessages) { 08127 res = ast_play_and_wait(chan, "vm-youhave"); 08128 if (!res) 08129 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08130 if (!res) { 08131 if ((vms->newmessages == 1)) { 08132 res = ast_play_and_wait(chan, "vm-INBOX"); 08133 if (!res) 08134 res = ast_play_and_wait(chan, "vm-message"); 08135 } else { 08136 res = ast_play_and_wait(chan, "vm-INBOXs"); 08137 if (!res) 08138 res = ast_play_and_wait(chan, "vm-messages"); 08139 } 08140 } 08141 } else if (vms->oldmessages){ 08142 res = ast_play_and_wait(chan, "vm-youhave"); 08143 if (!res) 08144 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08145 if ((vms->oldmessages == 1)){ 08146 res = ast_play_and_wait(chan, "vm-Old"); 08147 if (!res) 08148 res = ast_play_and_wait(chan, "vm-message"); 08149 } else { 08150 res = ast_play_and_wait(chan, "vm-Olds"); 08151 if (!res) 08152 res = ast_play_and_wait(chan, "vm-messages"); 08153 } 08154 } else if (!vms->oldmessages && !vms->newmessages) 08155 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08156 return res; 08157 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8256 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08257 { 08258 int res = 0; 08259 08260 /* Introduce messages they have */ 08261 if (!res) { 08262 if ((vms->newmessages) || (vms->oldmessages)) { 08263 res = ast_play_and_wait(chan, "vm-youhave"); 08264 } 08265 /* 08266 * The word "shtei" refers to the number 2 in hebrew when performing a count 08267 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08268 * an element, this is one of them. 08269 */ 08270 if (vms->newmessages) { 08271 if (!res) { 08272 if (vms->newmessages == 1) { 08273 res = ast_play_and_wait(chan, "vm-INBOX1"); 08274 } else { 08275 if (vms->newmessages == 2) { 08276 res = ast_play_and_wait(chan, "vm-shtei"); 08277 } else { 08278 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08279 } 08280 res = ast_play_and_wait(chan, "vm-INBOX"); 08281 } 08282 } 08283 if (vms->oldmessages && !res) { 08284 res = ast_play_and_wait(chan, "vm-and"); 08285 if (vms->oldmessages == 1) { 08286 res = ast_play_and_wait(chan, "vm-Old1"); 08287 } else { 08288 if (vms->oldmessages == 2) { 08289 res = ast_play_and_wait(chan, "vm-shtei"); 08290 } else { 08291 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08292 } 08293 res = ast_play_and_wait(chan, "vm-Old"); 08294 } 08295 } 08296 } 08297 if (!res && vms->oldmessages && !vms->newmessages) { 08298 if (!res) { 08299 if (vms->oldmessages == 1) { 08300 res = ast_play_and_wait(chan, "vm-Old1"); 08301 } else { 08302 if (vms->oldmessages == 2) { 08303 res = ast_play_and_wait(chan, "vm-shtei"); 08304 } else { 08305 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08306 } 08307 res = ast_play_and_wait(chan, "vm-Old"); 08308 } 08309 } 08310 } 08311 if (!res) { 08312 if (!vms->oldmessages && !vms->newmessages) { 08313 if (!res) { 08314 res = ast_play_and_wait(chan, "vm-nomessages"); 08315 } 08316 } 08317 } 08318 } 08319 return res; 08320 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8380 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08381 { 08382 /* Introduce messages they have */ 08383 int res; 08384 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08385 res = ast_play_and_wait(chan, "vm-no") || 08386 ast_play_and_wait(chan, "vm-message"); 08387 else 08388 res = ast_play_and_wait(chan, "vm-youhave"); 08389 if (!res && vms->newmessages) { 08390 res = (vms->newmessages == 1) ? 08391 ast_play_and_wait(chan, "digits/un") || 08392 ast_play_and_wait(chan, "vm-nuovo") || 08393 ast_play_and_wait(chan, "vm-message") : 08394 /* 2 or more new messages */ 08395 say_and_wait(chan, vms->newmessages, chan->language) || 08396 ast_play_and_wait(chan, "vm-nuovi") || 08397 ast_play_and_wait(chan, "vm-messages"); 08398 if (!res && vms->oldmessages) 08399 res = ast_play_and_wait(chan, "vm-and"); 08400 } 08401 if (!res && vms->oldmessages) { 08402 res = (vms->oldmessages == 1) ? 08403 ast_play_and_wait(chan, "digits/un") || 08404 ast_play_and_wait(chan, "vm-vecchio") || 08405 ast_play_and_wait(chan, "vm-message") : 08406 /* 2 or more old messages */ 08407 say_and_wait(chan, vms->oldmessages, chan->language) || 08408 ast_play_and_wait(chan, "vm-vecchi") || 08409 ast_play_and_wait(chan, "vm-messages"); 08410 } 08411 return res; 08412 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8216 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_counted_adjective(), ast_say_counted_noun(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08217 { 08218 int res; 08219 int lastnum = 0; 08220 08221 res = ast_play_and_wait(chan, "vm-youhave"); 08222 08223 if (!res && vms->newmessages) { 08224 lastnum = vms->newmessages; 08225 08226 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08227 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08228 } 08229 08230 if (!res && vms->oldmessages) { 08231 res = ast_play_and_wait(chan, "vm-and"); 08232 } 08233 } 08234 08235 if (!res && vms->oldmessages) { 08236 lastnum = vms->oldmessages; 08237 08238 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08239 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08240 } 08241 } 08242 08243 if (!res) { 08244 if (lastnum == 0) { 08245 res = ast_play_and_wait(chan, "vm-no"); 08246 } 08247 if (!res) { 08248 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08249 } 08250 } 08251 08252 return res; 08253 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8764 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08765 { 08766 /* Introduce messages they have */ 08767 int res; 08768 res = ast_play_and_wait(chan, "vm-youhave"); 08769 if (!res) { 08770 if (vms->newmessages) { 08771 res = say_and_wait(chan, vms->newmessages, chan->language); 08772 if (!res) { 08773 if (vms->newmessages == 1) 08774 res = ast_play_and_wait(chan, "vm-INBOXs"); 08775 else 08776 res = ast_play_and_wait(chan, "vm-INBOX"); 08777 } 08778 if (vms->oldmessages && !res) 08779 res = ast_play_and_wait(chan, "vm-and"); 08780 else if (!res) { 08781 if ((vms->newmessages == 1)) 08782 res = ast_play_and_wait(chan, "vm-message"); 08783 else 08784 res = ast_play_and_wait(chan, "vm-messages"); 08785 } 08786 08787 } 08788 if (!res && vms->oldmessages) { 08789 res = say_and_wait(chan, vms->oldmessages, chan->language); 08790 if (!res) { 08791 if (vms->oldmessages == 1) 08792 res = ast_play_and_wait(chan, "vm-Olds"); 08793 else 08794 res = ast_play_and_wait(chan, "vm-Old"); 08795 } 08796 if (!res) { 08797 if (vms->oldmessages == 1) 08798 res = ast_play_and_wait(chan, "vm-message"); 08799 else 08800 res = ast_play_and_wait(chan, "vm-messages"); 08801 } 08802 } 08803 if (!res) { 08804 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08805 res = ast_play_and_wait(chan, "vm-no"); 08806 if (!res) 08807 res = ast_play_and_wait(chan, "vm-messages"); 08808 } 08809 } 08810 } 08811 return res; 08812 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8530 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08531 { 08532 /* Introduce messages they have */ 08533 int res; 08534 08535 res = ast_play_and_wait(chan, "vm-youhave"); 08536 if (res) 08537 return res; 08538 08539 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08540 res = ast_play_and_wait(chan, "vm-no"); 08541 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08542 return res; 08543 } 08544 08545 if (vms->newmessages) { 08546 if ((vms->newmessages == 1)) { 08547 res = ast_play_and_wait(chan, "digits/1"); 08548 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08549 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08550 } else { 08551 res = say_and_wait(chan, vms->newmessages, chan->language); 08552 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08553 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08554 } 08555 if (!res && vms->oldmessages) 08556 res = ast_play_and_wait(chan, "vm-and"); 08557 } 08558 if (!res && vms->oldmessages) { 08559 if (vms->oldmessages == 1) { 08560 res = ast_play_and_wait(chan, "digits/1"); 08561 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08562 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08563 } else { 08564 res = say_and_wait(chan, vms->oldmessages, chan->language); 08565 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08566 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08567 } 08568 } 08569 08570 return res; 08571 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8415 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08416 { 08417 /* Introduce messages they have */ 08418 int res; 08419 div_t num; 08420 08421 if (!vms->oldmessages && !vms->newmessages) { 08422 res = ast_play_and_wait(chan, "vm-no"); 08423 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08424 return res; 08425 } else { 08426 res = ast_play_and_wait(chan, "vm-youhave"); 08427 } 08428 08429 if (vms->newmessages) { 08430 num = div(vms->newmessages, 10); 08431 if (vms->newmessages == 1) { 08432 res = ast_play_and_wait(chan, "digits/1-a"); 08433 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08434 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08435 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08436 if (num.rem == 2) { 08437 if (!num.quot) { 08438 res = ast_play_and_wait(chan, "digits/2-ie"); 08439 } else { 08440 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08441 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08442 } 08443 } else { 08444 res = say_and_wait(chan, vms->newmessages, chan->language); 08445 } 08446 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08447 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08448 } else { 08449 res = say_and_wait(chan, vms->newmessages, chan->language); 08450 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08451 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08452 } 08453 if (!res && vms->oldmessages) 08454 res = ast_play_and_wait(chan, "vm-and"); 08455 } 08456 if (!res && vms->oldmessages) { 08457 num = div(vms->oldmessages, 10); 08458 if (vms->oldmessages == 1) { 08459 res = ast_play_and_wait(chan, "digits/1-a"); 08460 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08461 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08462 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08463 if (num.rem == 2) { 08464 if (!num.quot) { 08465 res = ast_play_and_wait(chan, "digits/2-ie"); 08466 } else { 08467 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08468 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08469 } 08470 } else { 08471 res = say_and_wait(chan, vms->oldmessages, chan->language); 08472 } 08473 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08474 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08475 } else { 08476 res = say_and_wait(chan, vms->oldmessages, chan->language); 08477 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08478 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08479 } 08480 } 08481 08482 return res; 08483 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8815 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
08816 { 08817 /* Introduce messages they have */ 08818 int res; 08819 res = ast_play_and_wait(chan, "vm-youhave"); 08820 if (!res) { 08821 if (vms->newmessages) { 08822 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08823 if (!res) { 08824 if ((vms->newmessages == 1)) { 08825 res = ast_play_and_wait(chan, "vm-message"); 08826 if (!res) 08827 res = ast_play_and_wait(chan, "vm-INBOXs"); 08828 } else { 08829 res = ast_play_and_wait(chan, "vm-messages"); 08830 if (!res) 08831 res = ast_play_and_wait(chan, "vm-INBOX"); 08832 } 08833 } 08834 if (vms->oldmessages && !res) 08835 res = ast_play_and_wait(chan, "vm-and"); 08836 } 08837 if (!res && vms->oldmessages) { 08838 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08839 if (!res) { 08840 if (vms->oldmessages == 1) { 08841 res = ast_play_and_wait(chan, "vm-message"); 08842 if (!res) 08843 res = ast_play_and_wait(chan, "vm-Olds"); 08844 } else { 08845 res = ast_play_and_wait(chan, "vm-messages"); 08846 if (!res) 08847 res = ast_play_and_wait(chan, "vm-Old"); 08848 } 08849 } 08850 } 08851 if (!res) { 08852 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08853 res = ast_play_and_wait(chan, "vm-no"); 08854 if (!res) 08855 res = ast_play_and_wait(chan, "vm-messages"); 08856 } 08857 } 08858 } 08859 return res; 08860 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8676 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
08676 { 08677 /* Introduce messages they have */ 08678 int res; 08679 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08680 res = ast_play_and_wait(chan, "vm-nomessages"); 08681 return res; 08682 } else { 08683 res = ast_play_and_wait(chan, "vm-youhave"); 08684 } 08685 if (vms->newmessages) { 08686 if (!res) 08687 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08688 if ((vms->newmessages == 1)) { 08689 if (!res) 08690 res = ast_play_and_wait(chan, "vm-message"); 08691 if (!res) 08692 res = ast_play_and_wait(chan, "vm-INBOXs"); 08693 } else { 08694 if (!res) 08695 res = ast_play_and_wait(chan, "vm-messages"); 08696 if (!res) 08697 res = ast_play_and_wait(chan, "vm-INBOX"); 08698 } 08699 if (vms->oldmessages && !res) 08700 res = ast_play_and_wait(chan, "vm-and"); 08701 } 08702 if (vms->oldmessages) { 08703 if (!res) 08704 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08705 if (vms->oldmessages == 1) { 08706 if (!res) 08707 res = ast_play_and_wait(chan, "vm-message"); 08708 if (!res) 08709 res = ast_play_and_wait(chan, "vm-Olds"); 08710 } else { 08711 if (!res) 08712 res = ast_play_and_wait(chan, "vm-messages"); 08713 if (!res) 08714 res = ast_play_and_wait(chan, "vm-Old"); 08715 } 08716 } 08717 return res; 08718 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8486 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08487 { 08488 /* Introduce messages they have */ 08489 int res; 08490 08491 res = ast_play_and_wait(chan, "vm-youhave"); 08492 if (res) 08493 return res; 08494 08495 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08496 res = ast_play_and_wait(chan, "vm-no"); 08497 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08498 return res; 08499 } 08500 08501 if (vms->newmessages) { 08502 if ((vms->newmessages == 1)) { 08503 res = ast_play_and_wait(chan, "digits/ett"); 08504 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08505 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08506 } else { 08507 res = say_and_wait(chan, vms->newmessages, chan->language); 08508 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08509 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08510 } 08511 if (!res && vms->oldmessages) 08512 res = ast_play_and_wait(chan, "vm-and"); 08513 } 08514 if (!res && vms->oldmessages) { 08515 if (vms->oldmessages == 1) { 08516 res = ast_play_and_wait(chan, "digits/ett"); 08517 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08518 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08519 } else { 08520 res = say_and_wait(chan, vms->oldmessages, chan->language); 08521 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08522 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08523 } 08524 } 08525 08526 return res; 08527 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8978 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08979 { 08980 int res; 08981 08982 /* Introduce messages they have */ 08983 res = ast_play_and_wait(chan, "vm-youhave"); 08984 if (!res) { 08985 if (vms->newmessages) { 08986 res = say_and_wait(chan, vms->newmessages, chan->language); 08987 if (!res) 08988 res = ast_play_and_wait(chan, "vm-INBOX"); 08989 if (vms->oldmessages && !res) 08990 res = ast_play_and_wait(chan, "vm-and"); 08991 } 08992 if (!res && vms->oldmessages) { 08993 res = say_and_wait(chan, vms->oldmessages, chan->language); 08994 if (!res) 08995 res = ast_play_and_wait(chan, "vm-Old"); 08996 } 08997 if (!res) { 08998 if (!vms->oldmessages && !vms->newmessages) { 08999 res = ast_play_and_wait(chan, "vm-no"); 09000 if (!res) 09001 res = ast_play_and_wait(chan, "vm-message"); 09002 } 09003 } 09004 } 09005 return res; 09006 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8939 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08940 { 08941 int res; 08942 /* Introduce messages they have */ 08943 res = ast_play_and_wait(chan, "vm-you"); 08944 08945 if (!res && vms->newmessages) { 08946 res = ast_play_and_wait(chan, "vm-have"); 08947 if (!res) 08948 res = say_and_wait(chan, vms->newmessages, chan->language); 08949 if (!res) 08950 res = ast_play_and_wait(chan, "vm-tong"); 08951 if (!res) 08952 res = ast_play_and_wait(chan, "vm-INBOX"); 08953 if (vms->oldmessages && !res) 08954 res = ast_play_and_wait(chan, "vm-and"); 08955 else if (!res) 08956 res = ast_play_and_wait(chan, "vm-messages"); 08957 } 08958 if (!res && vms->oldmessages) { 08959 res = ast_play_and_wait(chan, "vm-have"); 08960 if (!res) 08961 res = say_and_wait(chan, vms->oldmessages, chan->language); 08962 if (!res) 08963 res = ast_play_and_wait(chan, "vm-tong"); 08964 if (!res) 08965 res = ast_play_and_wait(chan, "vm-Old"); 08966 if (!res) 08967 res = ast_play_and_wait(chan, "vm-messages"); 08968 } 08969 if (!res && !vms->oldmessages && !vms->newmessages) { 08970 res = ast_play_and_wait(chan, "vm-haveno"); 08971 if (!res) 08972 res = ast_play_and_wait(chan, "vm-messages"); 08973 } 08974 return res; 08975 }
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 3256 of file app_voicemail.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
03257 { 03258 switch (ast_lock_path(path)) { 03259 case AST_LOCK_TIMEOUT: 03260 return -1; 03261 default: 03262 return 0; 03263 } 03264 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1658 of file app_voicemail.c.
References my_umask, and VOICEMAIL_FILE_MODE.
Referenced by sendmail(), and sendpage().
01659 { 01660 FILE *p = NULL; 01661 int pfd = mkstemp(template); 01662 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01663 if (pfd > -1) { 01664 p = fdopen(pfd, "w+"); 01665 if (!p) { 01666 close(pfd); 01667 pfd = -1; 01668 } 01669 } 01670 return p; 01671 }
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 9181 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_debug, ast_fileexists(), ast_log(), AST_LOG_NOTICE, ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, check_password(), ast_vm_user::context, ext_pass_cmd, maxgreet, play_record_review(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, VM_FORCENAME, vm_invalid_password, vm_mismatch, vm_newpassword, vm_passchanged, vm_pls_try_again, vm_reenterpassword, and VM_SPOOL_DIR.
Referenced by vm_execmain().
09182 { 09183 int cmd = 0; 09184 int duration = 0; 09185 int tries = 0; 09186 char newpassword[80] = ""; 09187 char newpassword2[80] = ""; 09188 char prefile[PATH_MAX] = ""; 09189 unsigned char buf[256]; 09190 int bytes = 0; 09191 09192 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09193 if (ast_adsi_available(chan)) { 09194 bytes += adsi_logo(buf + bytes); 09195 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09196 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09197 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09198 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09199 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09200 } 09201 09202 /* If forcename is set, have the user record their name */ 09203 if (ast_test_flag(vmu, VM_FORCENAME)) { 09204 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09205 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09206 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09207 if (cmd < 0 || cmd == 't' || cmd == '#') 09208 return cmd; 09209 } 09210 } 09211 09212 /* If forcegreetings is set, have the user record their greetings */ 09213 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09214 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09215 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09216 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09217 if (cmd < 0 || cmd == 't' || cmd == '#') 09218 return cmd; 09219 } 09220 09221 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09222 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09223 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09224 if (cmd < 0 || cmd == 't' || cmd == '#') 09225 return cmd; 09226 } 09227 } 09228 09229 /* 09230 * Change the password last since new users will be able to skip over any steps this one comes before 09231 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09232 */ 09233 for (;;) { 09234 newpassword[1] = '\0'; 09235 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09236 if (cmd == '#') 09237 newpassword[0] = '\0'; 09238 if (cmd < 0 || cmd == 't' || cmd == '#') 09239 return cmd; 09240 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09241 if (cmd < 0 || cmd == 't' || cmd == '#') 09242 return cmd; 09243 cmd = check_password(vmu, newpassword); /* perform password validation */ 09244 if (cmd != 0) { 09245 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09246 cmd = ast_play_and_wait(chan, vm_invalid_password); 09247 } else { 09248 newpassword2[1] = '\0'; 09249 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09250 if (cmd == '#') 09251 newpassword2[0] = '\0'; 09252 if (cmd < 0 || cmd == 't' || cmd == '#') 09253 return cmd; 09254 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09255 if (cmd < 0 || cmd == 't' || cmd == '#') 09256 return cmd; 09257 if (!strcmp(newpassword, newpassword2)) 09258 break; 09259 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09260 cmd = ast_play_and_wait(chan, vm_mismatch); 09261 } 09262 if (++tries == 3) 09263 return -1; 09264 if (cmd != 0) { 09265 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09266 } 09267 } 09268 if (pwdchange & PWDCHANGE_INTERNAL) 09269 vm_change_password(vmu, newpassword); 09270 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09271 vm_change_password_shell(vmu, newpassword); 09272 09273 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09274 cmd = ast_play_and_wait(chan, vm_passchanged); 09275 09276 return cmd; 09277 }
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 9279 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_debug, ast_fileexists(), ast_log(), AST_LOG_NOTICE, ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_suite_event_notify, ast_waitfordigit(), check_password(), ast_vm_user::context, DISPOSE, ext_pass_cmd, ast_vm_user::mailbox, maxgreet, ast_vm_user::password, play_record_review(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, RETRIEVE, vm_state::username, vm_change_password(), vm_change_password_shell(), vm_invalid_password, vm_mismatch, vm_newpassword, vm_passchanged, vm_pls_try_again, vm_reenterpassword, VM_SPOOL_DIR, and vm_tempgreeting().
Referenced by vm_execmain().
09280 { 09281 int cmd = 0; 09282 int retries = 0; 09283 int duration = 0; 09284 char newpassword[80] = ""; 09285 char newpassword2[80] = ""; 09286 char prefile[PATH_MAX] = ""; 09287 unsigned char buf[256]; 09288 int bytes = 0; 09289 09290 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09291 if (ast_adsi_available(chan)) { 09292 bytes += adsi_logo(buf + bytes); 09293 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09294 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09295 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09296 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09297 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09298 } 09299 while ((cmd >= 0) && (cmd != 't')) { 09300 if (cmd) 09301 retries = 0; 09302 switch (cmd) { 09303 case '1': /* Record your unavailable message */ 09304 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09305 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09306 break; 09307 case '2': /* Record your busy message */ 09308 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09309 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09310 break; 09311 case '3': /* Record greeting */ 09312 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09313 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09314 break; 09315 case '4': /* manage the temporary greeting */ 09316 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09317 break; 09318 case '5': /* change password */ 09319 if (vmu->password[0] == '-') { 09320 cmd = ast_play_and_wait(chan, "vm-no"); 09321 break; 09322 } 09323 newpassword[1] = '\0'; 09324 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09325 if (cmd == '#') 09326 newpassword[0] = '\0'; 09327 else { 09328 if (cmd < 0) 09329 break; 09330 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09331 break; 09332 } 09333 } 09334 cmd = check_password(vmu, newpassword); /* perform password validation */ 09335 if (cmd != 0) { 09336 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09337 cmd = ast_play_and_wait(chan, vm_invalid_password); 09338 if (!cmd) { 09339 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09340 } 09341 break; 09342 } 09343 newpassword2[1] = '\0'; 09344 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09345 if (cmd == '#') 09346 newpassword2[0] = '\0'; 09347 else { 09348 if (cmd < 0) 09349 break; 09350 09351 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09352 break; 09353 } 09354 } 09355 if (strcmp(newpassword, newpassword2)) { 09356 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09357 cmd = ast_play_and_wait(chan, vm_mismatch); 09358 if (!cmd) { 09359 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09360 } 09361 break; 09362 } 09363 09364 if (pwdchange & PWDCHANGE_INTERNAL) { 09365 vm_change_password(vmu, newpassword); 09366 } 09367 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09368 vm_change_password_shell(vmu, newpassword); 09369 } 09370 09371 ast_debug(1, "User %s set password to %s of length %d\n", 09372 vms->username, newpassword, (int) strlen(newpassword)); 09373 cmd = ast_play_and_wait(chan, vm_passchanged); 09374 break; 09375 case '*': 09376 cmd = 't'; 09377 break; 09378 default: 09379 cmd = 0; 09380 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09381 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09382 if (ast_fileexists(prefile, NULL, NULL)) { 09383 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09384 } 09385 DISPOSE(prefile, -1); 09386 if (!cmd) { 09387 cmd = ast_play_and_wait(chan, "vm-options"); 09388 } 09389 if (!cmd) { 09390 cmd = ast_waitfordigit(chan, 6000); 09391 } 09392 if (!cmd) { 09393 retries++; 09394 } 09395 if (retries > 3) { 09396 cmd = 't'; 09397 } 09398 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09399 } 09400 } 09401 if (cmd == 't') 09402 cmd = 0; 09403 return cmd; 09404 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 8085 of file app_voicemail.c.
References ast_play_and_wait(), ast_channel::language, 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().
08086 { 08087 int cmd; 08088 08089 if ( !strncasecmp(chan->language, "it", 2) || 08090 !strncasecmp(chan->language, "es", 2) || 08091 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08092 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08093 return cmd ? cmd : ast_play_and_wait(chan, box); 08094 } else if (!strncasecmp(chan->language, "gr", 2)) { 08095 return vm_play_folder_name_gr(chan, box); 08096 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08097 return ast_play_and_wait(chan, box); 08098 } else if (!strncasecmp(chan->language, "pl", 2)) { 08099 return vm_play_folder_name_pl(chan, box); 08100 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08101 return vm_play_folder_name_ua(chan, box); 08102 } else if (!strncasecmp(chan->language, "vi", 2)) { 08103 return ast_play_and_wait(chan, box); 08104 } else { /* Default English */ 08105 cmd = ast_play_and_wait(chan, box); 08106 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08107 } 08108 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8038 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08039 { 08040 int cmd; 08041 char *buf; 08042 08043 buf = alloca(strlen(box) + 2); 08044 strcpy(buf, box); 08045 strcat(buf, "s"); 08046 08047 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08048 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08049 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08050 } else { 08051 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08052 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08053 } 08054 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8056 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08057 { 08058 int cmd; 08059 08060 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08061 if (!strcasecmp(box, "vm-INBOX")) 08062 cmd = ast_play_and_wait(chan, "vm-new-e"); 08063 else 08064 cmd = ast_play_and_wait(chan, "vm-old-e"); 08065 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08066 } else { 08067 cmd = ast_play_and_wait(chan, "vm-messages"); 08068 return cmd ? cmd : ast_play_and_wait(chan, box); 08069 } 08070 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8072 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08073 { 08074 int cmd; 08075 08076 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08077 cmd = ast_play_and_wait(chan, "vm-messages"); 08078 return cmd ? cmd : ast_play_and_wait(chan, box); 08079 } else { 08080 cmd = ast_play_and_wait(chan, box); 08081 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08082 } 08083 }
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 9422 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_fileexists(), ast_play_and_wait(), ast_test_suite_event_notify, ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::mailbox, maxgreet, play_record_review(), RETRIEVE, vm_state::username, and VM_SPOOL_DIR.
Referenced by vm_options().
09423 { 09424 int cmd = 0; 09425 int retries = 0; 09426 int duration = 0; 09427 char prefile[PATH_MAX] = ""; 09428 unsigned char buf[256]; 09429 int bytes = 0; 09430 09431 if (ast_adsi_available(chan)) { 09432 bytes += adsi_logo(buf + bytes); 09433 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09434 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09435 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09436 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09437 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09438 } 09439 09440 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09441 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09442 while ((cmd >= 0) && (cmd != 't')) { 09443 if (cmd) 09444 retries = 0; 09445 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09446 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09447 play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09448 cmd = 't'; 09449 } else { 09450 switch (cmd) { 09451 case '1': 09452 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09453 break; 09454 case '2': 09455 DELETE(prefile, -1, prefile, vmu); 09456 ast_play_and_wait(chan, "vm-tempremoved"); 09457 cmd = 't'; 09458 break; 09459 case '*': 09460 cmd = 't'; 09461 break; 09462 default: 09463 cmd = ast_play_and_wait(chan, 09464 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09465 "vm-tempgreeting2" : "vm-tempgreeting"); 09466 if (!cmd) { 09467 cmd = ast_waitfordigit(chan, 6000); 09468 } 09469 if (!cmd) { 09470 retries++; 09471 } 09472 if (retries > 3) { 09473 cmd = 't'; 09474 } 09475 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09476 } 09477 } 09478 DISPOSE(prefile, -1); 09479 } 09480 if (cmd == 't') 09481 cmd = 0; 09482 return cmd; 09483 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11385 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::list, user, and vm_users_data_provider_get_helper().
11387 { 11388 struct ast_vm_user *user; 11389 11390 AST_LIST_LOCK(&users); 11391 AST_LIST_TRAVERSE(&users, user, list) { 11392 vm_users_data_provider_get_helper(search, data_root, user); 11393 } 11394 AST_LIST_UNLOCK(&users); 11395 11396 return 0; 11397 }
static int vm_users_data_provider_get_helper | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root, | |||
struct ast_vm_user * | user | |||
) | [static] |
Definition at line 11338 of file app_voicemail.c.
References ast_data_add_int(), ast_data_add_node(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, inboxcount2(), vm_zone::list, vm_zone::name, and user.
Referenced by vm_users_data_provider_get().
11340 { 11341 struct ast_data *data_user, *data_zone; 11342 struct ast_data *data_state; 11343 struct vm_zone *zone = NULL; 11344 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11345 char ext_context[256] = ""; 11346 11347 data_user = ast_data_add_node(data_root, "user"); 11348 if (!data_user) { 11349 return -1; 11350 } 11351 11352 ast_data_add_structure(ast_vm_user, data_user, user); 11353 11354 AST_LIST_LOCK(&zones); 11355 AST_LIST_TRAVERSE(&zones, zone, list) { 11356 if (!strcmp(zone->name, user->zonetag)) { 11357 break; 11358 } 11359 } 11360 AST_LIST_UNLOCK(&zones); 11361 11362 /* state */ 11363 data_state = ast_data_add_node(data_user, "state"); 11364 if (!data_state) { 11365 return -1; 11366 } 11367 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11368 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11369 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11370 ast_data_add_int(data_state, "newmsg", newmsg); 11371 ast_data_add_int(data_state, "oldmsg", oldmsg); 11372 11373 if (zone) { 11374 data_zone = ast_data_add_node(data_user, "zone"); 11375 ast_data_add_structure(vm_zone, data_zone, zone); 11376 } 11377 11378 if (!ast_data_search_match(search, data_user)) { 11379 ast_data_remove_node(data_root, data_user); 11380 } 11381 11382 return 0; 11383 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11024 of file app_voicemail.c.
References ast_copy_string(), ast_goto_if_exists(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_channel::context, ast_vm_user::context, pbx_builtin_setvar_helper(), strsep(), and vm_authenticate().
Referenced by load_module().
11025 { 11026 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11027 struct ast_vm_user vmus; 11028 char *options = NULL; 11029 int silent = 0, skipuser = 0; 11030 int res = -1; 11031 11032 if (data) { 11033 s = ast_strdupa(data); 11034 user = strsep(&s, ","); 11035 options = strsep(&s, ","); 11036 if (user) { 11037 s = user; 11038 user = strsep(&s, "@"); 11039 context = strsep(&s, ""); 11040 if (!ast_strlen_zero(user)) 11041 skipuser++; 11042 ast_copy_string(mailbox, user, sizeof(mailbox)); 11043 } 11044 } 11045 11046 if (options) { 11047 silent = (strchr(options, 's')) != NULL; 11048 } 11049 11050 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11051 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11052 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11053 ast_play_and_wait(chan, "auth-thankyou"); 11054 res = 0; 11055 } else if (mailbox[0] == '*') { 11056 /* user entered '*' */ 11057 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11058 res = 0; /* prevent hangup */ 11059 } 11060 } 11061 11062 return res; 11063 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12542 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_log(), ast_say_character_str(), ast_strdupa, ast_stream_and_wait(), ast_strlen_zero(), ast_channel::language, LOG_WARNING, and sayname().
Referenced by load_module().
12543 { 12544 char *context; 12545 char *args_copy; 12546 int res; 12547 12548 if (ast_strlen_zero(data)) { 12549 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context"); 12550 return -1; 12551 } 12552 12553 args_copy = ast_strdupa(data); 12554 if ((context = strchr(args_copy, '@'))) { 12555 *context++ = '\0'; 12556 } else { 12557 context = "default"; 12558 } 12559 12560 if ((res = sayname(chan, args_copy, context) < 0)) { 12561 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12562 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12563 if (!res) { 12564 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12565 } 12566 } 12567 12568 return res; 12569 }
static struct ast_tm* vmu_tm | ( | const struct ast_vm_user * | vmu, | |
struct ast_tm * | tm | |||
) | [static] |
fill in *tm for current time according to the proper timezone, if any.
Definition at line 4411 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().
04412 { 04413 const struct vm_zone *z = NULL; 04414 struct timeval t = ast_tvnow(); 04415 04416 /* Does this user have a timezone specified? */ 04417 if (!ast_strlen_zero(vmu->zonetag)) { 04418 /* Find the zone in the list */ 04419 AST_LIST_LOCK(&zones); 04420 AST_LIST_TRAVERSE(&zones, z, list) { 04421 if (!strcmp(z->name, vmu->zonetag)) 04422 break; 04423 } 04424 AST_LIST_UNLOCK(&zones); 04425 } 04426 ast_localtime(&t, tm, z ? z->timezone : NULL); 04427 return tm; 04428 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7446 of file app_voicemail.c.
References ast_control_streamfile(), ast_test_suite_event_notify, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, and skipms.
Referenced by advanced_options(), ast_say_date_da(), ast_say_date_de(), ast_say_date_pt(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_es(), ast_say_date_with_format_fr(), ast_say_date_with_format_gr(), ast_say_date_with_format_he(), ast_say_date_with_format_it(), ast_say_date_with_format_nl(), ast_say_date_with_format_pl(), ast_say_date_with_format_pt(), ast_say_date_with_format_th(), ast_say_date_with_format_vi(), ast_say_date_with_format_zh(), ast_say_datetime_from_now_pt(), ast_say_number_full_pt(), ast_say_time_pt(), ast_say_time_pt_BR(), gr_say_number_female(), and play_message().
07447 { 07448 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07449 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); 07450 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7438 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_log(), and ast_stream_and_wait().
Referenced by play_message(), play_message_callerid(), and play_message_duration().
07439 { 07440 int res; 07441 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07442 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07443 return res; 07444 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12516 of file app_voicemail.c.
References ast_category_append(), ast_category_new(), ast_config_new(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), LOG_ERROR, and var.
Referenced by vm_change_password().
12516 { 12517 struct ast_config *conf; 12518 struct ast_category *cat; 12519 struct ast_variable *var; 12520 12521 if (!(conf=ast_config_new())) { 12522 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12523 return -1; 12524 } 12525 if (!(cat=ast_category_new("general","",1))) { 12526 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12527 return -1; 12528 } 12529 if (!(var=ast_variable_new("password",password,""))) { 12530 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12531 return -1; 12532 } 12533 ast_category_append(conf,cat); 12534 ast_variable_append(cat,var); 12535 if (ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12536 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12537 return -1; 12538 } 12539 return 0; 12540 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } [static] |
Definition at line 13621 of file app_voicemail.c.
char* addesc = "Comedian Mail" [static] |
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 896 of file app_voicemail.c.
Referenced by actual_load_config(), adsi_begin(), and adsi_load_vmail().
unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC" [static] |
Definition at line 897 of file app_voicemail.c.
Referenced by actual_load_config(), and adsi_load_vmail().
int adsiver = 1 [static] |
Definition at line 898 of file app_voicemail.c.
Referenced by actual_load_config(), adsi_begin(), and adsi_load_vmail().
char* app = "VoiceMail" [static] |
Definition at line 772 of file app_voicemail.c.
char* app2 = "VoiceMailMain" [static] |
Definition at line 775 of file app_voicemail.c.
char* app3 = "MailboxExists" [static] |
Definition at line 777 of file app_voicemail.c.
char* app4 = "VMAuthenticate" [static] |
Definition at line 778 of file app_voicemail.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 13621 of file app_voicemail.c.
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 882 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char charset[32] = "ISO-8859-1" [static] |
Definition at line 894 of file app_voicemail.c.
Referenced by actual_load_config(), ast_str_encode_mime(), make_email_file(), and tds_load_module().
char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static] |
Definition at line 885 of file app_voicemail.c.
Referenced by actual_load_config(), and play_message_callerid().
struct ast_cli_entry cli_voicemail[] [static] |
Initial value:
{ { .handler = handle_voicemail_show_users , .summary = "List defined voicemail boxes" ,__VA_ARGS__ }, { .handler = handle_voicemail_show_zones , .summary = "List zone message formats" ,__VA_ARGS__ }, { .handler = handle_voicemail_reload , .summary = "Reload voicemail configuration" ,__VA_ARGS__ }, }
Definition at line 11261 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 881 of file app_voicemail.c.
Referenced by actual_load_config(), dial_exec_full(), directory_exec(), populate_defaults(), ring_entry(), and wait_for_answer().
char* emailbody = NULL [static] |
Definition at line 888 of file app_voicemail.c.
Referenced by actual_load_config(), make_email_file(), and message_template_parse_emailbody().
char emaildateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 899 of file app_voicemail.c.
Referenced by actual_load_config(), make_email_file(), and prep_email_sub_vars().
char* emailsubject = NULL [static] |
Definition at line 889 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
char exitcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 883 of file app_voicemail.c.
Referenced by actual_load_config(), common_exec(), conf_run(), and populate_defaults().
char ext_pass_check_cmd[128] [static] |
char ext_pass_cmd[128] [static] |
Definition at line 748 of file app_voicemail.c.
Referenced by actual_load_config(), vm_change_password_shell(), vm_newuser(), and vm_options().
char externnotify[160] [static] |
Definition at line 792 of file app_voicemail.c.
Referenced by actual_load_config(), and run_externnotify().
char fromstring[100] [static] |
Definition at line 892 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
struct ast_flags globalflags = {0} [static] |
Definition at line 877 of file app_voicemail.c.
struct ao2_container* inprocess_container |
Definition at line 921 of file app_voicemail.c.
Referenced by inprocess_count(), load_module(), and unload_module().
char listen_control_forward_key[12] [static] |
Definition at line 850 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_pause_key[12] [static] |
Definition at line 852 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_restart_key[12] [static] |
Definition at line 853 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_reverse_key[12] [static] |
Definition at line 851 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_stop_key[12] [static] |
Definition at line 854 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char locale[20] [static] |
struct ast_custom_function mailbox_exists_acf [static] |
Initial value:
{ .name = "MAILBOX_EXISTS", .read = acf_mailbox_exists, }
Definition at line 11019 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
const char* const mailbox_folders[] [static] |
Definition at line 1694 of file app_voicemail.c.
char mailcmd[160] [static] |
Definition at line 791 of file app_voicemail.c.
Referenced by actual_load_config(), sendmail(), and sendpage().
int maxdeletedmsg [static] |
int maxgreet [static] |
Definition at line 798 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), vm_options(), and vm_tempgreeting().
int maxlogins [static] |
Definition at line 800 of file app_voicemail.c.
Referenced by actual_load_config(), and vm_execmain().
int maxmsg [static] |
Definition at line 787 of file app_voicemail.c.
Referenced by actual_load_config(), and copy_message().
int maxsilence [static] |
Definition at line 786 of file app_voicemail.c.
Referenced by actual_load_config(), ast_record_review(), play_record_review(), and vm_forwardoptions().
int minpassword [static] |
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 819 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 845 of file app_voicemail.c.
Referenced by load_module(), mwi_sub_event_cb(), mwi_unsub_event_cb(), and unload_module().
struct ast_event_sub* mwi_unsub_sub [static] |
Subscription to ... MWI event un-subscriptions
Definition at line 821 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
int my_umask [static] |
Definition at line 751 of file app_voicemail.c.
Referenced by add_email_attachment(), load_module(), and vm_mkftemp().
char* pagerbody = NULL [static] |
char pagerdateformat[32] = "%A, %B %d, %Y at %r" [static] |
char pagerfromstring[100] [static] |
char* pagersubject = NULL [static] |
int passwordlocation [static] |
ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 814 of file app_voicemail.c.
Referenced by mb_poll_thread(), and stop_poll_thread().
unsigned int poll_freq [static] |
Polling frequency
Definition at line 809 of file app_voicemail.c.
Referenced by actual_load_config(), and mb_poll_thread().
ast_mutex_t poll_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 813 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 806 of file app_voicemail.c.
Referenced by actual_load_config().
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 815 of file app_voicemail.c.
Referenced by actual_load_config(), start_poll_thread(), stop_poll_thread(), and unload_module().
unsigned char poll_thread_run [static] |
Definition at line 816 of file app_voicemail.c.
Referenced by mb_poll_thread(), start_poll_thread(), and stop_poll_thread().
int pwdchange = PWDCHANGE_INTERNAL [static] |
Definition at line 755 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
int saydurationminfo [static] |
Definition at line 879 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char* sayname_app = "VMSayName" [static] |
char serveremail[80] [static] |
Definition at line 790 of file app_voicemail.c.
Referenced by actual_load_config(), forward_message(), and notify_new_message().
int silencethreshold = 128 [static] |
Definition at line 789 of file app_voicemail.c.
Referenced by actual_load_config(), ast_record_review(), play_record_review(), setup_privacy_args(), and vm_forwardoptions().
int skipms [static] |
Definition at line 799 of file app_voicemail.c.
Referenced by actual_load_config(), controlplayback_exec(), handle_controlstreamfile(), and wait_file().
struct ast_smdi_interface* smdi_iface = NULL [static] |
Definition at line 793 of file app_voicemail.c.
Referenced by actual_load_config(), and run_externnotify().
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
struct ast_app_option vm_app_options[128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'd' ] = { .flag = OPT_DTMFEXIT , .arg_index = OPT_ARG_DTMFEXIT + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 }, [ 'U' ] = { .flag = OPT_MESSAGE_Urgent }, [ 'P' ] = { .flag = OPT_MESSAGE_PRIORITY }} [static] |
struct ast_data_entry vm_data_providers[] [static] |
char vm_invalid_password[80] = "vm-invalid-password" [static] |
Definition at line 862 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
char vm_mismatch[80] = "vm-mismatch" [static] |
Definition at line 861 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
char vm_newpassword[80] = "vm-newpassword" [static] |
Definition at line 858 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
char vm_passchanged[80] = "vm-passchanged" [static] |
Definition at line 859 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
char vm_password[80] = "vm-password" [static] |
Definition at line 857 of file app_voicemail.c.
Referenced by actual_load_config(), and vm_authenticate().
char vm_pls_try_again[80] = "vm-pls-try-again" [static] |
Definition at line 863 of file app_voicemail.c.
Referenced by actual_load_config(), vm_forwardoptions(), vm_newuser(), and vm_options().
char vm_prepend_timeout[80] = "vm-then-pound" [static] |
Definition at line 875 of file app_voicemail.c.
Referenced by actual_load_config(), and vm_forwardoptions().
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 860 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
char VM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 746 of file app_voicemail.c.
Referenced by __has_voicemail(), actual_load_config(), append_mailbox(), forward_message(), invent_message(), leave_voicemail(), load_module(), make_dir(), notify_new_message(), play_message_callerid(), sayname(), vm_change_password(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().
struct ast_data_handler vm_users_data_provider [static] |
Initial value:
{ .version = AST_DATA_HANDLER_VERSION, .get = vm_users_data_provider_get }
Definition at line 11399 of file app_voicemail.c.
char vmfmts[80] [static] |
Definition at line 794 of file app_voicemail.c.
Referenced by actual_load_config(), forward_message(), and vm_execmain().
int vmmaxsecs [static] |
int vmminsecs [static] |
double volgain [static] |
char zonetag[80] [static] |
Definition at line 784 of file app_voicemail.c.
Referenced by actual_load_config(), and build_peer().