#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 = "ac1f6a56484a8820659555499174e588" , .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 11333 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 11361 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 5377 of file app_voicemail.c.
References ast_strlen_zero(), and VM_SPOOL_DIR.
Referenced by has_voicemail(), inboxcount2(), and messagecount().
05378 { 05379 DIR *dir; 05380 struct dirent *de; 05381 char fn[256]; 05382 int ret = 0; 05383 05384 /* If no mailbox, return immediately */ 05385 if (ast_strlen_zero(mailbox)) 05386 return 0; 05387 05388 if (ast_strlen_zero(folder)) 05389 folder = "INBOX"; 05390 if (ast_strlen_zero(context)) 05391 context = "default"; 05392 05393 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05394 05395 if (!(dir = opendir(fn))) 05396 return 0; 05397 05398 while ((de = readdir(dir))) { 05399 if (!strncasecmp(de->d_name, "msg", 3)) { 05400 if (shortcircuit) { 05401 ret = 1; 05402 break; 05403 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05404 ret++; 05405 } 05406 } 05407 } 05408 05409 closedir(dir); 05410 05411 return ret; 05412 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 13680 of file app_voicemail.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 13680 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 11035 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().
11036 { 11037 struct ast_vm_user svm; 11038 AST_DECLARE_APP_ARGS(arg, 11039 AST_APP_ARG(mbox); 11040 AST_APP_ARG(context); 11041 ); 11042 11043 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11044 11045 if (ast_strlen_zero(arg.mbox)) { 11046 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11047 return -1; 11048 } 11049 11050 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11051 return 0; 11052 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11871 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().
11872 { 11873 struct ast_vm_user *current; 11874 char *cat; 11875 struct ast_variable *var; 11876 const char *val; 11877 char *q, *stringp, *tmp; 11878 int x; 11879 int tmpadsi[4]; 11880 char secretfn[PATH_MAX] = ""; 11881 11882 #ifdef IMAP_STORAGE 11883 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11884 #endif 11885 /* set audio control prompts */ 11886 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11887 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11888 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11889 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11890 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11891 11892 /* Free all the users structure */ 11893 free_vm_users(); 11894 11895 /* Free all the zones structure */ 11896 free_vm_zones(); 11897 11898 AST_LIST_LOCK(&users); 11899 11900 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11901 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11902 11903 if (cfg) { 11904 /* General settings */ 11905 11906 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11907 val = "default"; 11908 ast_copy_string(userscontext, val, sizeof(userscontext)); 11909 /* Attach voice message to mail message ? */ 11910 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11911 val = "yes"; 11912 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11913 11914 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11915 val = "no"; 11916 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11917 11918 volgain = 0.0; 11919 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11920 sscanf(val, "%30lf", &volgain); 11921 11922 #ifdef ODBC_STORAGE 11923 strcpy(odbc_database, "asterisk"); 11924 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11925 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11926 } 11927 strcpy(odbc_table, "voicemessages"); 11928 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11929 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11930 } 11931 #endif 11932 /* Mail command */ 11933 strcpy(mailcmd, SENDMAIL); 11934 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11935 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11936 11937 maxsilence = 0; 11938 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11939 maxsilence = atoi(val); 11940 if (maxsilence > 0) 11941 maxsilence *= 1000; 11942 } 11943 11944 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11945 maxmsg = MAXMSG; 11946 } else { 11947 maxmsg = atoi(val); 11948 if (maxmsg < 0) { 11949 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11950 maxmsg = MAXMSG; 11951 } else if (maxmsg > MAXMSGLIMIT) { 11952 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11953 maxmsg = MAXMSGLIMIT; 11954 } 11955 } 11956 11957 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11958 maxdeletedmsg = 0; 11959 } else { 11960 if (sscanf(val, "%30d", &x) == 1) 11961 maxdeletedmsg = x; 11962 else if (ast_true(val)) 11963 maxdeletedmsg = MAXMSG; 11964 else 11965 maxdeletedmsg = 0; 11966 11967 if (maxdeletedmsg < 0) { 11968 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11969 maxdeletedmsg = MAXMSG; 11970 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11971 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11972 maxdeletedmsg = MAXMSGLIMIT; 11973 } 11974 } 11975 11976 /* Load date format config for voicemail mail */ 11977 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11978 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11979 } 11980 11981 /* Load date format config for voicemail pager mail */ 11982 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11983 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11984 } 11985 11986 /* External password changing command */ 11987 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11988 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11989 pwdchange = PWDCHANGE_EXTERNAL; 11990 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 11991 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11992 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 11993 } 11994 11995 /* External password validation command */ 11996 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 11997 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 11998 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 11999 } 12000 12001 #ifdef IMAP_STORAGE 12002 /* IMAP server address */ 12003 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 12004 ast_copy_string(imapserver, val, sizeof(imapserver)); 12005 } else { 12006 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 12007 } 12008 /* IMAP server port */ 12009 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 12010 ast_copy_string(imapport, val, sizeof(imapport)); 12011 } else { 12012 ast_copy_string(imapport, "143", sizeof(imapport)); 12013 } 12014 /* IMAP server flags */ 12015 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 12016 ast_copy_string(imapflags, val, sizeof(imapflags)); 12017 } 12018 /* IMAP server master username */ 12019 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 12020 ast_copy_string(authuser, val, sizeof(authuser)); 12021 } 12022 /* IMAP server master password */ 12023 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 12024 ast_copy_string(authpassword, val, sizeof(authpassword)); 12025 } 12026 /* Expunge on exit */ 12027 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 12028 if (ast_false(val)) 12029 expungeonhangup = 0; 12030 else 12031 expungeonhangup = 1; 12032 } else { 12033 expungeonhangup = 1; 12034 } 12035 /* IMAP voicemail folder */ 12036 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 12037 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12038 } else { 12039 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12040 } 12041 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12042 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12043 } 12044 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12045 imapgreetings = ast_true(val); 12046 } else { 12047 imapgreetings = 0; 12048 } 12049 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12050 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12051 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12052 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12053 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12054 } else { 12055 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12056 } 12057 12058 /* There is some very unorthodox casting done here. This is due 12059 * to the way c-client handles the argument passed in. It expects a 12060 * void pointer and casts the pointer directly to a long without 12061 * first dereferencing it. */ 12062 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12063 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12064 } else { 12065 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12066 } 12067 12068 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12069 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12070 } else { 12071 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12072 } 12073 12074 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12075 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12076 } else { 12077 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12078 } 12079 12080 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12081 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12082 } else { 12083 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12084 } 12085 12086 /* Increment configuration version */ 12087 imapversion++; 12088 #endif 12089 /* External voicemail notify application */ 12090 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12091 ast_copy_string(externnotify, val, sizeof(externnotify)); 12092 ast_debug(1, "found externnotify: %s\n", externnotify); 12093 } else { 12094 externnotify[0] = '\0'; 12095 } 12096 12097 /* SMDI voicemail notification */ 12098 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12099 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12100 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12101 smdi_iface = ast_smdi_interface_find(val); 12102 } else { 12103 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12104 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12105 } 12106 if (!smdi_iface) { 12107 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12108 } 12109 } 12110 12111 /* Silence treshold */ 12112 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12113 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12114 silencethreshold = atoi(val); 12115 12116 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12117 val = ASTERISK_USERNAME; 12118 ast_copy_string(serveremail, val, sizeof(serveremail)); 12119 12120 vmmaxsecs = 0; 12121 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12122 if (sscanf(val, "%30d", &x) == 1) { 12123 vmmaxsecs = x; 12124 } else { 12125 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12126 } 12127 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12128 static int maxmessage_deprecate = 0; 12129 if (maxmessage_deprecate == 0) { 12130 maxmessage_deprecate = 1; 12131 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12132 } 12133 if (sscanf(val, "%30d", &x) == 1) { 12134 vmmaxsecs = x; 12135 } else { 12136 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12137 } 12138 } 12139 12140 vmminsecs = 0; 12141 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12142 if (sscanf(val, "%30d", &x) == 1) { 12143 vmminsecs = x; 12144 if (maxsilence / 1000 >= vmminsecs) { 12145 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12146 } 12147 } else { 12148 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12149 } 12150 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12151 static int maxmessage_deprecate = 0; 12152 if (maxmessage_deprecate == 0) { 12153 maxmessage_deprecate = 1; 12154 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12155 } 12156 if (sscanf(val, "%30d", &x) == 1) { 12157 vmminsecs = x; 12158 if (maxsilence / 1000 >= vmminsecs) { 12159 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12160 } 12161 } else { 12162 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12163 } 12164 } 12165 12166 val = ast_variable_retrieve(cfg, "general", "format"); 12167 if (!val) { 12168 val = "wav"; 12169 } else { 12170 tmp = ast_strdupa(val); 12171 val = ast_format_str_reduce(tmp); 12172 if (!val) { 12173 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12174 val = "wav"; 12175 } 12176 } 12177 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12178 12179 skipms = 3000; 12180 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12181 if (sscanf(val, "%30d", &x) == 1) { 12182 maxgreet = x; 12183 } else { 12184 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12185 } 12186 } 12187 12188 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12189 if (sscanf(val, "%30d", &x) == 1) { 12190 skipms = x; 12191 } else { 12192 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12193 } 12194 } 12195 12196 maxlogins = 3; 12197 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12198 if (sscanf(val, "%30d", &x) == 1) { 12199 maxlogins = x; 12200 } else { 12201 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12202 } 12203 } 12204 12205 minpassword = MINPASSWORD; 12206 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12207 if (sscanf(val, "%30d", &x) == 1) { 12208 minpassword = x; 12209 } else { 12210 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12211 } 12212 } 12213 12214 /* Force new user to record name ? */ 12215 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12216 val = "no"; 12217 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12218 12219 /* Force new user to record greetings ? */ 12220 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12221 val = "no"; 12222 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12223 12224 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12225 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12226 stringp = ast_strdupa(val); 12227 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12228 if (!ast_strlen_zero(stringp)) { 12229 q = strsep(&stringp, ","); 12230 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12231 q++; 12232 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12233 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12234 } else { 12235 cidinternalcontexts[x][0] = '\0'; 12236 } 12237 } 12238 } 12239 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12240 ast_debug(1, "VM Review Option disabled globally\n"); 12241 val = "no"; 12242 } 12243 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12244 12245 /* Temporary greeting reminder */ 12246 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12247 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12248 val = "no"; 12249 } else { 12250 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12251 } 12252 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12253 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12254 ast_debug(1, "VM next message wrap disabled globally\n"); 12255 val = "no"; 12256 } 12257 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12258 12259 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12260 ast_debug(1, "VM Operator break disabled globally\n"); 12261 val = "no"; 12262 } 12263 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12264 12265 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12266 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12267 val = "no"; 12268 } 12269 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12270 12271 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12272 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12273 val = "no"; 12274 } 12275 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12276 12277 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12278 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12279 val = "yes"; 12280 } 12281 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12282 12283 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12284 ast_debug(1, "Move Heard enabled globally\n"); 12285 val = "yes"; 12286 } 12287 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12288 12289 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12290 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12291 val = "no"; 12292 } 12293 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12294 12295 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12296 ast_debug(1, "Duration info before msg enabled globally\n"); 12297 val = "yes"; 12298 } 12299 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12300 12301 saydurationminfo = 2; 12302 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12303 if (sscanf(val, "%30d", &x) == 1) { 12304 saydurationminfo = x; 12305 } else { 12306 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12307 } 12308 } 12309 12310 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12311 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12312 val = "no"; 12313 } 12314 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12315 12316 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12317 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12318 ast_debug(1, "found dialout context: %s\n", dialcontext); 12319 } else { 12320 dialcontext[0] = '\0'; 12321 } 12322 12323 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12324 ast_copy_string(callcontext, val, sizeof(callcontext)); 12325 ast_debug(1, "found callback context: %s\n", callcontext); 12326 } else { 12327 callcontext[0] = '\0'; 12328 } 12329 12330 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12331 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12332 ast_debug(1, "found operator context: %s\n", exitcontext); 12333 } else { 12334 exitcontext[0] = '\0'; 12335 } 12336 12337 /* load password sounds configuration */ 12338 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12339 ast_copy_string(vm_password, val, sizeof(vm_password)); 12340 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12341 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12342 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12343 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12344 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12345 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12346 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12347 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12348 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12349 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12350 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12351 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12352 } 12353 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12354 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12355 } 12356 /* load configurable audio prompts */ 12357 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12358 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12359 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12360 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12361 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12362 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12363 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12364 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12365 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12366 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12367 12368 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12369 val = "no"; 12370 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12371 12372 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12373 val = "voicemail.conf"; 12374 } 12375 if (!(strcmp(val, "spooldir"))) { 12376 passwordlocation = OPT_PWLOC_SPOOLDIR; 12377 } else { 12378 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12379 } 12380 12381 poll_freq = DEFAULT_POLL_FREQ; 12382 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12383 if (sscanf(val, "%30u", &poll_freq) != 1) { 12384 poll_freq = DEFAULT_POLL_FREQ; 12385 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12386 } 12387 } 12388 12389 poll_mailboxes = 0; 12390 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12391 poll_mailboxes = ast_true(val); 12392 12393 memset(fromstring, 0, sizeof(fromstring)); 12394 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12395 strcpy(charset, "ISO-8859-1"); 12396 if (emailbody) { 12397 ast_free(emailbody); 12398 emailbody = NULL; 12399 } 12400 if (emailsubject) { 12401 ast_free(emailsubject); 12402 emailsubject = NULL; 12403 } 12404 if (pagerbody) { 12405 ast_free(pagerbody); 12406 pagerbody = NULL; 12407 } 12408 if (pagersubject) { 12409 ast_free(pagersubject); 12410 pagersubject = NULL; 12411 } 12412 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12413 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12414 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12415 ast_copy_string(fromstring, val, sizeof(fromstring)); 12416 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12417 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12418 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12419 ast_copy_string(charset, val, sizeof(charset)); 12420 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12421 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12422 for (x = 0; x < 4; x++) { 12423 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12424 } 12425 } 12426 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12427 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12428 for (x = 0; x < 4; x++) { 12429 memcpy(&adsisec[x], &tmpadsi[x], 1); 12430 } 12431 } 12432 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12433 if (atoi(val)) { 12434 adsiver = atoi(val); 12435 } 12436 } 12437 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12438 ast_copy_string(zonetag, val, sizeof(zonetag)); 12439 } 12440 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12441 ast_copy_string(locale, val, sizeof(locale)); 12442 } 12443 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12444 emailsubject = ast_strdup(substitute_escapes(val)); 12445 } 12446 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12447 emailbody = ast_strdup(substitute_escapes(val)); 12448 } 12449 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12450 pagersubject = ast_strdup(substitute_escapes(val)); 12451 } 12452 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12453 pagerbody = ast_strdup(substitute_escapes(val)); 12454 } 12455 12456 /* load mailboxes from users.conf */ 12457 if (ucfg) { 12458 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12459 if (!strcasecmp(cat, "general")) { 12460 continue; 12461 } 12462 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12463 continue; 12464 if ((current = find_or_create(userscontext, cat))) { 12465 populate_defaults(current); 12466 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12467 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12468 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12469 current->passwordlocation = OPT_PWLOC_USERSCONF; 12470 } 12471 12472 switch (current->passwordlocation) { 12473 case OPT_PWLOC_SPOOLDIR: 12474 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12475 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12476 } 12477 } 12478 } 12479 } 12480 12481 /* load mailboxes from voicemail.conf */ 12482 cat = ast_category_browse(cfg, NULL); 12483 while (cat) { 12484 if (strcasecmp(cat, "general")) { 12485 var = ast_variable_browse(cfg, cat); 12486 if (strcasecmp(cat, "zonemessages")) { 12487 /* Process mailboxes in this context */ 12488 while (var) { 12489 append_mailbox(cat, var->name, var->value); 12490 var = var->next; 12491 } 12492 } else { 12493 /* Timezones in this context */ 12494 while (var) { 12495 struct vm_zone *z; 12496 if ((z = ast_malloc(sizeof(*z)))) { 12497 char *msg_format, *tzone; 12498 msg_format = ast_strdupa(var->value); 12499 tzone = strsep(&msg_format, "|,"); 12500 if (msg_format) { 12501 ast_copy_string(z->name, var->name, sizeof(z->name)); 12502 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12503 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12504 AST_LIST_LOCK(&zones); 12505 AST_LIST_INSERT_HEAD(&zones, z, list); 12506 AST_LIST_UNLOCK(&zones); 12507 } else { 12508 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12509 ast_free(z); 12510 } 12511 } else { 12512 AST_LIST_UNLOCK(&users); 12513 return -1; 12514 } 12515 var = var->next; 12516 } 12517 } 12518 } 12519 cat = ast_category_browse(cfg, cat); 12520 } 12521 12522 AST_LIST_UNLOCK(&users); 12523 12524 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12525 start_poll_thread(); 12526 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12527 stop_poll_thread();; 12528 12529 return 0; 12530 } else { 12531 AST_LIST_UNLOCK(&users); 12532 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12533 return 0; 12534 } 12535 }
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 4791 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().
04792 { 04793 char tmpdir[256], newtmp[256]; 04794 char fname[256]; 04795 char tmpcmd[256]; 04796 int tmpfd = -1; 04797 int soxstatus = 0; 04798 04799 /* Eww. We want formats to tell us their own MIME type */ 04800 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04801 04802 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04803 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04804 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04805 tmpfd = mkstemp(newtmp); 04806 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04807 ast_debug(3, "newtmp: %s\n", newtmp); 04808 if (tmpfd > -1) { 04809 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04810 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04811 attach = newtmp; 04812 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04813 } else { 04814 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04815 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04816 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04817 } 04818 } 04819 } 04820 fprintf(p, "--%s" ENDL, bound); 04821 if (msgnum > -1) 04822 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04823 else 04824 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04825 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04826 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04827 if (msgnum > -1) 04828 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04829 else 04830 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04831 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04832 base_encode(fname, p); 04833 if (last) 04834 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04835 if (tmpfd > -1) { 04836 if (soxstatus == 0) { 04837 unlink(fname); 04838 } 04839 close(tmpfd); 04840 unlink(newtmp); 04841 } 04842 return 0; 04843 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6397 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().
06398 { 06399 int x; 06400 if (!ast_adsi_available(chan)) 06401 return; 06402 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06403 if (x < 0) 06404 return; 06405 if (!x) { 06406 if (adsi_load_vmail(chan, useadsi)) { 06407 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06408 return; 06409 } 06410 } else 06411 *useadsi = 1; 06412 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6592 of file app_voicemail.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), and vm_state::curmsg.
Referenced by vm_execmain().
06593 { 06594 int bytes = 0; 06595 unsigned char buf[256]; 06596 unsigned char keys[8]; 06597 06598 int x; 06599 06600 if (!ast_adsi_available(chan)) 06601 return; 06602 06603 /* New meaning for keys */ 06604 for (x = 0; x < 5; x++) 06605 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06606 06607 keys[6] = 0x0; 06608 keys[7] = 0x0; 06609 06610 if (!vms->curmsg) { 06611 /* No prev key, provide "Folder" instead */ 06612 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06613 } 06614 if (vms->curmsg >= vms->lastmsg) { 06615 /* If last message ... */ 06616 if (vms->curmsg) { 06617 /* but not only message, provide "Folder" instead */ 06618 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06619 } else { 06620 /* Otherwise if only message, leave blank */ 06621 keys[3] = 1; 06622 } 06623 } 06624 06625 /* If deleted, show "undeleted" */ 06626 #ifdef IMAP_STORAGE 06627 ast_mutex_lock(&vms->lock); 06628 #endif 06629 if (vms->deleted[vms->curmsg]) { 06630 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06631 } 06632 #ifdef IMAP_STORAGE 06633 ast_mutex_unlock(&vms->lock); 06634 #endif 06635 06636 /* Except "Exit" */ 06637 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06638 bytes += ast_adsi_set_keys(buf + bytes, keys); 06639 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06640 06641 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06642 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6462 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().
06463 { 06464 unsigned char buf[256]; 06465 int bytes = 0; 06466 unsigned char keys[8]; 06467 int x, y; 06468 06469 if (!ast_adsi_available(chan)) 06470 return; 06471 06472 for (x = 0; x < 5; x++) { 06473 y = ADSI_KEY_APPS + 12 + start + x; 06474 if (y > ADSI_KEY_APPS + 12 + 4) 06475 y = 0; 06476 keys[x] = ADSI_KEY_SKT | y; 06477 } 06478 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06479 keys[6] = 0; 06480 keys[7] = 0; 06481 06482 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06483 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06484 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06485 bytes += ast_adsi_set_keys(buf + bytes, keys); 06486 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06487 06488 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06489 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6747 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().
06748 { 06749 unsigned char buf[256]; 06750 int bytes = 0; 06751 06752 if (!ast_adsi_available(chan)) 06753 return; 06754 bytes += adsi_logo(buf + bytes); 06755 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06756 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06757 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06758 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06759 06760 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06761 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6268 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().
06269 { 06270 unsigned char buf[256]; 06271 int bytes = 0; 06272 int x; 06273 char num[5]; 06274 06275 *useadsi = 0; 06276 bytes += ast_adsi_data_mode(buf + bytes); 06277 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06278 06279 bytes = 0; 06280 bytes += adsi_logo(buf); 06281 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06282 #ifdef DISPLAY 06283 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06284 #endif 06285 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06286 bytes += ast_adsi_data_mode(buf + bytes); 06287 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06288 06289 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06290 bytes = 0; 06291 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06292 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06293 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06294 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06295 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06296 return 0; 06297 } 06298 06299 #ifdef DISPLAY 06300 /* Add a dot */ 06301 bytes = 0; 06302 bytes += ast_adsi_logo(buf); 06303 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06304 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06305 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06306 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06307 #endif 06308 bytes = 0; 06309 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06310 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06311 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06312 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06313 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06314 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06315 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06316 06317 #ifdef DISPLAY 06318 /* Add another dot */ 06319 bytes = 0; 06320 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06321 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06322 06323 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06324 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06325 #endif 06326 06327 bytes = 0; 06328 /* These buttons we load but don't use yet */ 06329 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06330 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06331 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06332 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06333 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06334 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06335 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06336 06337 #ifdef DISPLAY 06338 /* Add another dot */ 06339 bytes = 0; 06340 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06341 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06342 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06343 #endif 06344 06345 bytes = 0; 06346 for (x = 0; x < 5; x++) { 06347 snprintf(num, sizeof(num), "%d", x); 06348 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06349 } 06350 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06351 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06352 06353 #ifdef DISPLAY 06354 /* Add another dot */ 06355 bytes = 0; 06356 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06357 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06358 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06359 #endif 06360 06361 if (ast_adsi_end_download(chan)) { 06362 bytes = 0; 06363 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06364 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06365 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06366 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06367 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06368 return 0; 06369 } 06370 bytes = 0; 06371 bytes += ast_adsi_download_disconnect(buf + bytes); 06372 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06373 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06374 06375 ast_debug(1, "Done downloading scripts...\n"); 06376 06377 #ifdef DISPLAY 06378 /* Add last dot */ 06379 bytes = 0; 06380 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06381 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06382 #endif 06383 ast_debug(1, "Restarting session...\n"); 06384 06385 bytes = 0; 06386 /* Load the session now */ 06387 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06388 *useadsi = 1; 06389 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06390 } else 06391 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06392 06393 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06394 return 0; 06395 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6414 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().
06415 { 06416 unsigned char buf[256]; 06417 int bytes = 0; 06418 unsigned char keys[8]; 06419 int x; 06420 if (!ast_adsi_available(chan)) 06421 return; 06422 06423 for (x = 0; x < 8; x++) 06424 keys[x] = 0; 06425 /* Set one key for next */ 06426 keys[3] = ADSI_KEY_APPS + 3; 06427 06428 bytes += adsi_logo(buf + bytes); 06429 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06430 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06431 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06432 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06433 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06434 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06435 bytes += ast_adsi_set_keys(buf + bytes, keys); 06436 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06437 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06438 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6260 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().
06261 { 06262 int bytes = 0; 06263 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06264 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06265 return bytes; 06266 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6491 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().
06492 { 06493 int bytes = 0; 06494 unsigned char buf[256]; 06495 char buf1[256], buf2[256]; 06496 char fn2[PATH_MAX]; 06497 06498 char cid[256] = ""; 06499 char *val; 06500 char *name, *num; 06501 char datetime[21] = ""; 06502 FILE *f; 06503 06504 unsigned char keys[8]; 06505 06506 int x; 06507 06508 if (!ast_adsi_available(chan)) 06509 return; 06510 06511 /* Retrieve important info */ 06512 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06513 f = fopen(fn2, "r"); 06514 if (f) { 06515 while (!feof(f)) { 06516 if (!fgets((char *) buf, sizeof(buf), f)) { 06517 continue; 06518 } 06519 if (!feof(f)) { 06520 char *stringp = NULL; 06521 stringp = (char *) buf; 06522 strsep(&stringp, "="); 06523 val = strsep(&stringp, "="); 06524 if (!ast_strlen_zero(val)) { 06525 if (!strcmp((char *) buf, "callerid")) 06526 ast_copy_string(cid, val, sizeof(cid)); 06527 if (!strcmp((char *) buf, "origdate")) 06528 ast_copy_string(datetime, val, sizeof(datetime)); 06529 } 06530 } 06531 } 06532 fclose(f); 06533 } 06534 /* New meaning for keys */ 06535 for (x = 0; x < 5; x++) 06536 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06537 keys[6] = 0x0; 06538 keys[7] = 0x0; 06539 06540 if (!vms->curmsg) { 06541 /* No prev key, provide "Folder" instead */ 06542 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06543 } 06544 if (vms->curmsg >= vms->lastmsg) { 06545 /* If last message ... */ 06546 if (vms->curmsg) { 06547 /* but not only message, provide "Folder" instead */ 06548 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06549 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06550 06551 } else { 06552 /* Otherwise if only message, leave blank */ 06553 keys[3] = 1; 06554 } 06555 } 06556 06557 if (!ast_strlen_zero(cid)) { 06558 ast_callerid_parse(cid, &name, &num); 06559 if (!name) 06560 name = num; 06561 } else 06562 name = "Unknown Caller"; 06563 06564 /* If deleted, show "undeleted" */ 06565 #ifdef IMAP_STORAGE 06566 ast_mutex_lock(&vms->lock); 06567 #endif 06568 if (vms->deleted[vms->curmsg]) { 06569 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06570 } 06571 #ifdef IMAP_STORAGE 06572 ast_mutex_unlock(&vms->lock); 06573 #endif 06574 06575 /* Except "Exit" */ 06576 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06577 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06578 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06579 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06580 06581 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06582 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06583 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06584 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06585 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06586 bytes += ast_adsi_set_keys(buf + bytes, keys); 06587 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06588 06589 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06590 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6440 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().
06441 { 06442 unsigned char buf[256]; 06443 int bytes = 0; 06444 unsigned char keys[8]; 06445 int x; 06446 if (!ast_adsi_available(chan)) 06447 return; 06448 06449 for (x = 0; x < 8; x++) 06450 keys[x] = 0; 06451 /* Set one key for next */ 06452 keys[3] = ADSI_KEY_APPS + 3; 06453 06454 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06455 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06456 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06457 bytes += ast_adsi_set_keys(buf + bytes, keys); 06458 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06459 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06460 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6644 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(), buf2, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_execmain().
06645 { 06646 unsigned char buf[256] = ""; 06647 char buf1[256] = "", buf2[256] = ""; 06648 int bytes = 0; 06649 unsigned char keys[8]; 06650 int x; 06651 06652 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06653 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06654 if (!ast_adsi_available(chan)) 06655 return; 06656 if (vms->newmessages) { 06657 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06658 if (vms->oldmessages) { 06659 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06660 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06661 } else { 06662 snprintf(buf2, sizeof(buf2), "%s.", newm); 06663 } 06664 } else if (vms->oldmessages) { 06665 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06666 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06667 } else { 06668 strcpy(buf1, "You have no messages."); 06669 buf2[0] = ' '; 06670 buf2[1] = '\0'; 06671 } 06672 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06673 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06674 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06675 06676 for (x = 0; x < 6; x++) 06677 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06678 keys[6] = 0; 06679 keys[7] = 0; 06680 06681 /* Don't let them listen if there are none */ 06682 if (vms->lastmsg < 0) 06683 keys[0] = 1; 06684 bytes += ast_adsi_set_keys(buf + bytes, keys); 06685 06686 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06687 06688 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06689 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6691 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(), buf2, vm_state::curbox, and vm_state::lastmsg.
Referenced by vm_execmain().
06692 { 06693 unsigned char buf[256] = ""; 06694 char buf1[256] = "", buf2[256] = ""; 06695 int bytes = 0; 06696 unsigned char keys[8]; 06697 int x; 06698 06699 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06700 06701 if (!ast_adsi_available(chan)) 06702 return; 06703 06704 /* Original command keys */ 06705 for (x = 0; x < 6; x++) 06706 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06707 06708 keys[6] = 0; 06709 keys[7] = 0; 06710 06711 if ((vms->lastmsg + 1) < 1) 06712 keys[0] = 0; 06713 06714 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06715 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06716 06717 if (vms->lastmsg + 1) 06718 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06719 else 06720 strcpy(buf2, "no messages."); 06721 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06722 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06723 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06724 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06725 bytes += ast_adsi_set_keys(buf + bytes, keys); 06726 06727 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06728 06729 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06730 06731 }
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 13242 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_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().
13243 { 13244 int res = 0; 13245 char filename[PATH_MAX]; 13246 struct ast_config *msg_cfg = NULL; 13247 const char *origtime, *context; 13248 char *name, *num; 13249 int retries = 0; 13250 char *cid; 13251 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13252 13253 vms->starting = 0; 13254 13255 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13256 13257 /* Retrieve info from VM attribute file */ 13258 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13259 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13260 msg_cfg = ast_config_load(filename, config_flags); 13261 DISPOSE(vms->curdir, vms->curmsg); 13262 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 13263 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13264 return 0; 13265 } 13266 13267 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13268 ast_config_destroy(msg_cfg); 13269 return 0; 13270 } 13271 13272 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13273 13274 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13275 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13276 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13277 switch (option) { 13278 case 3: /* Play message envelope */ 13279 if (!res) 13280 res = play_message_datetime(chan, vmu, origtime, filename); 13281 if (!res) 13282 res = play_message_callerid(chan, vms, cid, context, 0); 13283 13284 res = 't'; 13285 break; 13286 13287 case 2: /* Call back */ 13288 13289 if (ast_strlen_zero(cid)) 13290 break; 13291 13292 ast_callerid_parse(cid, &name, &num); 13293 while ((res > -1) && (res != 't')) { 13294 switch (res) { 13295 case '1': 13296 if (num) { 13297 /* Dial the CID number */ 13298 res = dialout(chan, vmu, num, vmu->callback); 13299 if (res) { 13300 ast_config_destroy(msg_cfg); 13301 return 9; 13302 } 13303 } else { 13304 res = '2'; 13305 } 13306 break; 13307 13308 case '2': 13309 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13310 if (!ast_strlen_zero(vmu->dialout)) { 13311 res = dialout(chan, vmu, NULL, vmu->dialout); 13312 if (res) { 13313 ast_config_destroy(msg_cfg); 13314 return 9; 13315 } 13316 } else { 13317 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13318 res = ast_play_and_wait(chan, "vm-sorry"); 13319 } 13320 ast_config_destroy(msg_cfg); 13321 return res; 13322 case '*': 13323 res = 't'; 13324 break; 13325 case '3': 13326 case '4': 13327 case '5': 13328 case '6': 13329 case '7': 13330 case '8': 13331 case '9': 13332 case '0': 13333 13334 res = ast_play_and_wait(chan, "vm-sorry"); 13335 retries++; 13336 break; 13337 default: 13338 if (num) { 13339 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13340 res = ast_play_and_wait(chan, "vm-num-i-have"); 13341 if (!res) 13342 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13343 if (!res) 13344 res = ast_play_and_wait(chan, "vm-tocallnum"); 13345 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13346 if (!ast_strlen_zero(vmu->dialout)) { 13347 if (!res) 13348 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13349 } 13350 } else { 13351 res = ast_play_and_wait(chan, "vm-nonumber"); 13352 if (!ast_strlen_zero(vmu->dialout)) { 13353 if (!res) 13354 res = ast_play_and_wait(chan, "vm-toenternumber"); 13355 } 13356 } 13357 if (!res) { 13358 res = ast_play_and_wait(chan, "vm-star-cancel"); 13359 } 13360 if (!res) { 13361 res = ast_waitfordigit(chan, 6000); 13362 } 13363 if (!res) { 13364 retries++; 13365 if (retries > 3) { 13366 res = 't'; 13367 } 13368 } 13369 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13370 break; 13371 13372 } 13373 if (res == 't') 13374 res = 0; 13375 else if (res == '*') 13376 res = -1; 13377 } 13378 break; 13379 13380 case 1: /* Reply */ 13381 /* Send reply directly to sender */ 13382 if (ast_strlen_zero(cid)) 13383 break; 13384 13385 ast_callerid_parse(cid, &name, &num); 13386 if (!num) { 13387 ast_verb(3, "No CID number available, no reply sent\n"); 13388 if (!res) 13389 res = ast_play_and_wait(chan, "vm-nonumber"); 13390 ast_config_destroy(msg_cfg); 13391 return res; 13392 } else { 13393 struct ast_vm_user vmu2; 13394 if (find_user(&vmu2, vmu->context, num)) { 13395 struct leave_vm_options leave_options; 13396 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13397 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13398 13399 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13400 13401 memset(&leave_options, 0, sizeof(leave_options)); 13402 leave_options.record_gain = record_gain; 13403 res = leave_voicemail(chan, mailbox, &leave_options); 13404 if (!res) 13405 res = 't'; 13406 ast_config_destroy(msg_cfg); 13407 return res; 13408 } else { 13409 /* Sender has no mailbox, can't reply */ 13410 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13411 ast_play_and_wait(chan, "vm-nobox"); 13412 res = 't'; 13413 ast_config_destroy(msg_cfg); 13414 return res; 13415 } 13416 } 13417 res = 0; 13418 13419 break; 13420 } 13421 13422 #ifndef IMAP_STORAGE 13423 ast_config_destroy(msg_cfg); 13424 13425 if (!res) { 13426 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13427 vms->heard[msg] = 1; 13428 res = wait_file(chan, vms, vms->fn); 13429 } 13430 #endif 13431 return res; 13432 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10762 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().
10763 { 10764 /* Assumes lock is already held */ 10765 char *tmp; 10766 char *stringp; 10767 char *s; 10768 struct ast_vm_user *vmu; 10769 char *mailbox_full; 10770 int new = 0, old = 0, urgent = 0; 10771 char secretfn[PATH_MAX] = ""; 10772 10773 tmp = ast_strdupa(data); 10774 10775 if (!(vmu = find_or_create(context, box))) 10776 return -1; 10777 10778 populate_defaults(vmu); 10779 10780 stringp = tmp; 10781 if ((s = strsep(&stringp, ","))) { 10782 if (!ast_strlen_zero(s) && s[0] == '*') { 10783 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10784 "\n\tmust be reset in voicemail.conf.\n", box); 10785 } 10786 /* assign password regardless of validity to prevent NULL password from being assigned */ 10787 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10788 } 10789 if (stringp && (s = strsep(&stringp, ","))) { 10790 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10791 } 10792 if (stringp && (s = strsep(&stringp, ","))) { 10793 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10794 } 10795 if (stringp && (s = strsep(&stringp, ","))) { 10796 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10797 } 10798 if (stringp && (s = strsep(&stringp, ","))) { 10799 apply_options(vmu, s); 10800 } 10801 10802 switch (vmu->passwordlocation) { 10803 case OPT_PWLOC_SPOOLDIR: 10804 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10805 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10806 } 10807 10808 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 10809 strcpy(mailbox_full, box); 10810 strcat(mailbox_full, "@"); 10811 strcat(mailbox_full, context); 10812 10813 inboxcount2(mailbox_full, &urgent, &new, &old); 10814 queue_mwi_event(mailbox_full, urgent, new, old); 10815 10816 return 0; 10817 }
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 4466 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.
04467 { 04468 struct ast_str *tmp = ast_str_alloca(80); 04469 int first_section = 1; 04470 04471 ast_str_reset(*end); 04472 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04473 for (; *start; start++) { 04474 int need_encoding = 0; 04475 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04476 need_encoding = 1; 04477 } 04478 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04479 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04480 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04481 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04482 /* Start new line */ 04483 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04484 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04485 first_section = 0; 04486 } 04487 if (need_encoding && *start == ' ') { 04488 ast_str_append(&tmp, -1, "_"); 04489 } else if (need_encoding) { 04490 ast_str_append(&tmp, -1, "=%hhX", *start); 04491 } else { 04492 ast_str_append(&tmp, -1, "%c", *start); 04493 } 04494 } 04495 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04496 return ast_str_buffer(*end); 04497 }
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 4394 of file app_voicemail.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
04395 { 04396 const char *ptr; 04397 04398 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04399 ast_str_set(buf, maxlen, "\""); 04400 for (ptr = from; *ptr; ptr++) { 04401 if (*ptr == '"' || *ptr == '\\') { 04402 ast_str_append(buf, maxlen, "\\%c", *ptr); 04403 } else { 04404 ast_str_append(buf, maxlen, "%c", *ptr); 04405 } 04406 } 04407 ast_str_append(buf, maxlen, "\""); 04408 04409 return ast_str_buffer(*buf); 04410 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10819 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.
10820 { 10821 int res = 0; 10822 struct ast_vm_user *vmu; 10823 /* language parameter seems to only be used for display in manager action */ 10824 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10825 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10826 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10827 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10828 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10829 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10830 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10831 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10832 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10833 #ifdef IMAP_STORAGE 10834 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10835 "imapfolder=INBOX|imapvmshareid=6000"; 10836 #endif 10837 10838 switch (cmd) { 10839 case TEST_INIT: 10840 info->name = "vmuser"; 10841 info->category = "/apps/app_voicemail/"; 10842 info->summary = "Vmuser unit test"; 10843 info->description = 10844 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10845 return AST_TEST_NOT_RUN; 10846 case TEST_EXECUTE: 10847 break; 10848 } 10849 10850 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10851 return AST_TEST_NOT_RUN; 10852 } 10853 ast_set_flag(vmu, VM_ALLOCED); 10854 populate_defaults(vmu); 10855 10856 apply_options(vmu, options_string); 10857 10858 if (!ast_test_flag(vmu, VM_ATTACH)) { 10859 ast_test_status_update(test, "Parse failure for attach option\n"); 10860 res = 1; 10861 } 10862 if (strcasecmp(vmu->attachfmt, "wav49")) { 10863 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10864 res = 1; 10865 } 10866 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10867 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10868 res = 1; 10869 } 10870 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10871 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10872 res = 1; 10873 } 10874 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10875 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10876 res = 1; 10877 } 10878 if (strcasecmp(vmu->zonetag, "central")) { 10879 ast_test_status_update(test, "Parse failure for tz option\n"); 10880 res = 1; 10881 } 10882 if (!ast_test_flag(vmu, VM_DELETE)) { 10883 ast_test_status_update(test, "Parse failure for delete option\n"); 10884 res = 1; 10885 } 10886 if (!ast_test_flag(vmu, VM_SAYCID)) { 10887 ast_test_status_update(test, "Parse failure for saycid option\n"); 10888 res = 1; 10889 } 10890 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10891 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10892 res = 1; 10893 } 10894 if (!ast_test_flag(vmu, VM_REVIEW)) { 10895 ast_test_status_update(test, "Parse failure for review option\n"); 10896 res = 1; 10897 } 10898 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10899 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10900 res = 1; 10901 } 10902 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10903 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10904 res = 1; 10905 } 10906 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10907 ast_test_status_update(test, "Parse failure for operator option\n"); 10908 res = 1; 10909 } 10910 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10911 ast_test_status_update(test, "Parse failure for envelope option\n"); 10912 res = 1; 10913 } 10914 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10915 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10916 res = 1; 10917 } 10918 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10919 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10920 res = 1; 10921 } 10922 if (vmu->saydurationm != 5) { 10923 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10924 res = 1; 10925 } 10926 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10927 ast_test_status_update(test, "Parse failure for forcename option\n"); 10928 res = 1; 10929 } 10930 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10931 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10932 res = 1; 10933 } 10934 if (strcasecmp(vmu->callback, "somecontext")) { 10935 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10936 res = 1; 10937 } 10938 if (strcasecmp(vmu->dialout, "somecontext2")) { 10939 ast_test_status_update(test, "Parse failure for dialout option\n"); 10940 res = 1; 10941 } 10942 if (strcasecmp(vmu->exit, "somecontext3")) { 10943 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10944 res = 1; 10945 } 10946 if (vmu->minsecs != 10) { 10947 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10948 res = 1; 10949 } 10950 if (vmu->maxsecs != 100) { 10951 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10952 res = 1; 10953 } 10954 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10955 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10956 res = 1; 10957 } 10958 if (vmu->maxdeletedmsg != 50) { 10959 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10960 res = 1; 10961 } 10962 if (vmu->volgain != 1.3) { 10963 ast_test_status_update(test, "Parse failure for volgain option\n"); 10964 res = 1; 10965 } 10966 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10967 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10968 res = 1; 10969 } 10970 #ifdef IMAP_STORAGE 10971 apply_options(vmu, option_string2); 10972 10973 if (strcasecmp(vmu->imapuser, "imapuser")) { 10974 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10975 res = 1; 10976 } 10977 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10978 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10979 res = 1; 10980 } 10981 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10982 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10983 res = 1; 10984 } 10985 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10986 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10987 res = 1; 10988 } 10989 #endif 10990 10991 free_user(vmu); 10992 return res ? AST_TEST_FAIL : AST_TEST_PASS; 10993 }
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 4270 of file app_voicemail.c.
References ast_log(), BASEMAXINLINE, ENDL, errno, inchar(), and ochar().
04271 { 04272 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04273 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04274 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04275 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04276 int i, hiteof = 0; 04277 FILE *fi; 04278 struct baseio bio; 04279 04280 memset(&bio, 0, sizeof(bio)); 04281 bio.iocp = BASEMAXINLINE; 04282 04283 if (!(fi = fopen(filename, "rb"))) { 04284 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04285 return -1; 04286 } 04287 04288 while (!hiteof){ 04289 unsigned char igroup[3], ogroup[4]; 04290 int c, n; 04291 04292 memset(igroup, 0, sizeof(igroup)); 04293 04294 for (n = 0; n < 3; n++) { 04295 if ((c = inchar(&bio, fi)) == EOF) { 04296 hiteof = 1; 04297 break; 04298 } 04299 04300 igroup[n] = (unsigned char) c; 04301 } 04302 04303 if (n > 0) { 04304 ogroup[0]= dtable[igroup[0] >> 2]; 04305 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04306 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04307 ogroup[3]= dtable[igroup[2] & 0x3F]; 04308 04309 if (n < 3) { 04310 ogroup[3] = '='; 04311 04312 if (n < 2) 04313 ogroup[2] = '='; 04314 } 04315 04316 for (i = 0; i < 4; i++) 04317 ochar(&bio, ogroup[i], so); 04318 } 04319 } 04320 04321 fclose(fi); 04322 04323 if (fputs(ENDL, so) == EOF) { 04324 return 0; 04325 } 04326 04327 return 1; 04328 }
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 4439 of file app_voicemail.c.
04440 { 04441 for (; *str; str++) { 04442 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 04443 return 1; 04444 } 04445 } 04446 return 0; 04447 }
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 7957 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().
07958 { 07959 int x = 0; 07960 int last_msg_idx = 0; 07961 07962 #ifndef IMAP_STORAGE 07963 int res = 0, nummsg; 07964 char fn2[PATH_MAX]; 07965 #endif 07966 07967 if (vms->lastmsg <= -1) { 07968 goto done; 07969 } 07970 07971 vms->curmsg = -1; 07972 #ifndef IMAP_STORAGE 07973 /* Get the deleted messages fixed */ 07974 if (vm_lock_path(vms->curdir)) { 07975 return ERROR_LOCK_PATH; 07976 } 07977 07978 /* update count as message may have arrived while we've got mailbox open */ 07979 last_msg_idx = last_message_index(vmu, vms->curdir); 07980 if (last_msg_idx != vms->lastmsg) { 07981 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 07982 } 07983 07984 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 07985 for (x = 0; x < last_msg_idx + 1; x++) { 07986 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07987 /* Save this message. It's not in INBOX or hasn't been heard */ 07988 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07989 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 07990 break; 07991 } 07992 vms->curmsg++; 07993 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 07994 if (strcmp(vms->fn, fn2)) { 07995 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07996 } 07997 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07998 /* Move to old folder before deleting */ 07999 res = save_to_folder(vmu, vms, x, 1); 08000 if (res == ERROR_LOCK_PATH) { 08001 /* If save failed do not delete the message */ 08002 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 08003 vms->deleted[x] = 0; 08004 vms->heard[x] = 0; 08005 --x; 08006 } 08007 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 08008 /* Move to deleted folder */ 08009 res = save_to_folder(vmu, vms, x, 10); 08010 if (res == ERROR_LOCK_PATH) { 08011 /* If save failed do not delete the message */ 08012 vms->deleted[x] = 0; 08013 vms->heard[x] = 0; 08014 --x; 08015 } 08016 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 08017 /* If realtime storage enabled - we should explicitly delete this message, 08018 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08019 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08020 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08021 DELETE(vms->curdir, x, vms->fn, vmu); 08022 } 08023 } 08024 } 08025 08026 /* Delete ALL remaining messages */ 08027 nummsg = x - 1; 08028 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08029 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08030 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08031 DELETE(vms->curdir, x, vms->fn, vmu); 08032 } 08033 } 08034 ast_unlock_path(vms->curdir); 08035 #else /* defined(IMAP_STORAGE) */ 08036 ast_mutex_lock(&vms->lock); 08037 if (vms->deleted) { 08038 /* Since we now expunge after each delete, deleting in reverse order 08039 * ensures that no reordering occurs between each step. */ 08040 last_msg_idx = vms->dh_arraysize; 08041 for (x = last_msg_idx - 1; x >= 0; x--) { 08042 if (vms->deleted[x]) { 08043 ast_debug(3, "IMAP delete of %d\n", x); 08044 DELETE(vms->curdir, x, vms->fn, vmu); 08045 } 08046 } 08047 } 08048 #endif 08049 08050 done: 08051 if (vms->deleted) { 08052 ast_free(vms->deleted); 08053 vms->deleted = NULL; 08054 } 08055 if (vms->heard) { 08056 ast_free(vms->heard); 08057 vms->heard = NULL; 08058 } 08059 vms->dh_arraysize = 0; 08060 #ifdef IMAP_STORAGE 08061 ast_mutex_unlock(&vms->lock); 08062 #endif 08063 08064 return 0; 08065 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 11139 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().
11140 { 11141 int which = 0; 11142 int wordlen; 11143 struct ast_vm_user *vmu; 11144 const char *context = ""; 11145 11146 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11147 if (pos > 4) 11148 return NULL; 11149 if (pos == 3) 11150 return (state == 0) ? ast_strdup("for") : NULL; 11151 wordlen = strlen(word); 11152 AST_LIST_TRAVERSE(&users, vmu, list) { 11153 if (!strncasecmp(word, vmu->context, wordlen)) { 11154 if (context && strcmp(context, vmu->context) && ++which > state) 11155 return ast_strdup(vmu->context); 11156 /* ignore repeated contexts ? */ 11157 context = vmu->context; 11158 } 11159 } 11160 return NULL; 11161 }
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 4075 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().
04076 { 04077 int ifd; 04078 int ofd; 04079 int res; 04080 int len; 04081 char buf[4096]; 04082 04083 #ifdef HARDLINK_WHEN_POSSIBLE 04084 /* Hard link if possible; saves disk space & is faster */ 04085 if (link(infile, outfile)) { 04086 #endif 04087 if ((ifd = open(infile, O_RDONLY)) < 0) { 04088 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04089 return -1; 04090 } 04091 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04092 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04093 close(ifd); 04094 return -1; 04095 } 04096 do { 04097 len = read(ifd, buf, sizeof(buf)); 04098 if (len < 0) { 04099 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04100 close(ifd); 04101 close(ofd); 04102 unlink(outfile); 04103 } else if (len) { 04104 res = write(ofd, buf, len); 04105 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04106 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04107 close(ifd); 04108 close(ofd); 04109 unlink(outfile); 04110 } 04111 } 04112 } while (len); 04113 close(ifd); 04114 close(ofd); 04115 return 0; 04116 #ifdef HARDLINK_WHEN_POSSIBLE 04117 } else { 04118 /* Hard link succeeded */ 04119 return 0; 04120 } 04121 #endif 04122 }
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 5311 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().
05312 { 05313 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05314 const char *frombox = mbox(vmu, imbox); 05315 const char *userfolder; 05316 int recipmsgnum; 05317 int res = 0; 05318 05319 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05320 05321 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05322 userfolder = "Urgent"; 05323 } else { 05324 userfolder = "INBOX"; 05325 } 05326 05327 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05328 05329 if (!dir) 05330 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05331 else 05332 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05333 05334 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05335 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05336 05337 if (vm_lock_path(todir)) 05338 return ERROR_LOCK_PATH; 05339 05340 recipmsgnum = last_message_index(recip, todir) + 1; 05341 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05342 make_file(topath, sizeof(topath), todir, recipmsgnum); 05343 #ifndef ODBC_STORAGE 05344 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05345 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05346 } else { 05347 #endif 05348 /* If we are prepending a message for ODBC, then the message already 05349 * exists in the database, but we want to force copying from the 05350 * filesystem (since only the FS contains the prepend). */ 05351 copy_plain_file(frompath, topath); 05352 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05353 vm_delete(topath); 05354 #ifndef ODBC_STORAGE 05355 } 05356 #endif 05357 } else { 05358 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05359 res = -1; 05360 } 05361 ast_unlock_path(todir); 05362 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05363 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05364 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05365 flag); 05366 05367 return res; 05368 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Definition at line 4133 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().
04134 { 04135 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04136 struct ast_variable *tmp,*var = NULL; 04137 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04138 ast_filecopy(frompath, topath, NULL); 04139 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04140 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04141 if (ast_check_realtime("voicemail_data")) { 04142 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04143 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04144 for (tmp = var; tmp; tmp = tmp->next) { 04145 if (!strcasecmp(tmp->name, "origmailbox")) { 04146 origmailbox = tmp->value; 04147 } else if (!strcasecmp(tmp->name, "context")) { 04148 context = tmp->value; 04149 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04150 macrocontext = tmp->value; 04151 } else if (!strcasecmp(tmp->name, "exten")) { 04152 exten = tmp->value; 04153 } else if (!strcasecmp(tmp->name, "priority")) { 04154 priority = tmp->value; 04155 } else if (!strcasecmp(tmp->name, "callerchan")) { 04156 callerchan = tmp->value; 04157 } else if (!strcasecmp(tmp->name, "callerid")) { 04158 callerid = tmp->value; 04159 } else if (!strcasecmp(tmp->name, "origdate")) { 04160 origdate = tmp->value; 04161 } else if (!strcasecmp(tmp->name, "origtime")) { 04162 origtime = tmp->value; 04163 } else if (!strcasecmp(tmp->name, "category")) { 04164 category = tmp->value; 04165 } else if (!strcasecmp(tmp->name, "duration")) { 04166 duration = tmp->value; 04167 } 04168 } 04169 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); 04170 } 04171 copy(frompath2, topath2); 04172 ast_variables_destroy(var); 04173 }
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 3970 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().
03971 { 03972 03973 int vmcount = 0; 03974 DIR *vmdir = NULL; 03975 struct dirent *vment = NULL; 03976 03977 if (vm_lock_path(dir)) 03978 return ERROR_LOCK_PATH; 03979 03980 if ((vmdir = opendir(dir))) { 03981 while ((vment = readdir(vmdir))) { 03982 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03983 vmcount++; 03984 } 03985 } 03986 closedir(vmdir); 03987 } 03988 ast_unlock_path(dir); 03989 03990 return vmcount; 03991 }
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 13169 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().
13170 { 13171 int cmd = 0; 13172 char destination[80] = ""; 13173 int retries = 0; 13174 13175 if (!num) { 13176 ast_verb(3, "Destination number will be entered manually\n"); 13177 while (retries < 3 && cmd != 't') { 13178 destination[1] = '\0'; 13179 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13180 if (!cmd) 13181 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13182 if (!cmd) 13183 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13184 if (!cmd) { 13185 cmd = ast_waitfordigit(chan, 6000); 13186 if (cmd) 13187 destination[0] = cmd; 13188 } 13189 if (!cmd) { 13190 retries++; 13191 } else { 13192 13193 if (cmd < 0) 13194 return 0; 13195 if (cmd == '*') { 13196 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13197 return 0; 13198 } 13199 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13200 retries++; 13201 else 13202 cmd = 't'; 13203 } 13204 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13205 } 13206 if (retries >= 3) { 13207 return 0; 13208 } 13209 13210 } else { 13211 if (option_verbose > 2) 13212 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13213 ast_copy_string(destination, num, sizeof(destination)); 13214 } 13215 13216 if (!ast_strlen_zero(destination)) { 13217 if (destination[strlen(destination) -1 ] == '*') 13218 return 0; 13219 if (option_verbose > 2) 13220 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13221 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13222 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13223 chan->priority = 0; 13224 return 9; 13225 } 13226 return 0; 13227 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static] |
Definition at line 10722 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().
10723 { 10724 struct ast_vm_user *vmu; 10725 10726 if (!ast_strlen_zero(box) && box[0] == '*') { 10727 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10728 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10729 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10730 "\n\tand will be ignored.\n", box, context); 10731 return NULL; 10732 } 10733 10734 AST_LIST_TRAVERSE(&users, vmu, list) { 10735 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10736 if (strcasecmp(vmu->context, context)) { 10737 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10738 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10739 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10740 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10741 } 10742 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10743 return NULL; 10744 } 10745 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10746 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10747 return NULL; 10748 } 10749 } 10750 10751 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10752 return NULL; 10753 10754 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10755 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10756 10757 AST_LIST_INSERT_TAIL(&users, vmu, list); 10758 10759 return vmu; 10760 }
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 7158 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().
07159 { 07160 #ifdef IMAP_STORAGE 07161 int todircount = 0; 07162 struct vm_state *dstvms; 07163 #endif 07164 char username[70]=""; 07165 char fn[PATH_MAX]; /* for playback of name greeting */ 07166 char ecodes[16] = "#"; 07167 int res = 0, cmd = 0; 07168 struct ast_vm_user *receiver = NULL, *vmtmp; 07169 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07170 char *stringp; 07171 const char *s; 07172 int saved_messages = 0; 07173 int valid_extensions = 0; 07174 char *dir; 07175 int curmsg; 07176 char urgent_str[7] = ""; 07177 int prompt_played = 0; 07178 #ifndef IMAP_STORAGE 07179 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07180 #endif 07181 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07182 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07183 } 07184 07185 if (vms == NULL) return -1; 07186 dir = vms->curdir; 07187 curmsg = vms->curmsg; 07188 07189 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07190 while (!res && !valid_extensions) { 07191 int use_directory = 0; 07192 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07193 int done = 0; 07194 int retries = 0; 07195 cmd = 0; 07196 while ((cmd >= 0) && !done ){ 07197 if (cmd) 07198 retries = 0; 07199 switch (cmd) { 07200 case '1': 07201 use_directory = 0; 07202 done = 1; 07203 break; 07204 case '2': 07205 use_directory = 1; 07206 done = 1; 07207 break; 07208 case '*': 07209 cmd = 't'; 07210 done = 1; 07211 break; 07212 default: 07213 /* Press 1 to enter an extension press 2 to use the directory */ 07214 cmd = ast_play_and_wait(chan, "vm-forward"); 07215 if (!cmd) { 07216 cmd = ast_waitfordigit(chan, 3000); 07217 } 07218 if (!cmd) { 07219 retries++; 07220 } 07221 if (retries > 3) { 07222 cmd = 't'; 07223 done = 1; 07224 } 07225 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07226 } 07227 } 07228 if (cmd < 0 || cmd == 't') 07229 break; 07230 } 07231 07232 if (use_directory) { 07233 /* use app_directory */ 07234 07235 char old_context[sizeof(chan->context)]; 07236 char old_exten[sizeof(chan->exten)]; 07237 int old_priority; 07238 struct ast_app* directory_app; 07239 07240 directory_app = pbx_findapp("Directory"); 07241 if (directory_app) { 07242 char vmcontext[256]; 07243 /* make backup copies */ 07244 memcpy(old_context, chan->context, sizeof(chan->context)); 07245 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07246 old_priority = chan->priority; 07247 07248 /* call the the Directory, changes the channel */ 07249 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07250 res = pbx_exec(chan, directory_app, vmcontext); 07251 07252 ast_copy_string(username, chan->exten, sizeof(username)); 07253 07254 /* restore the old context, exten, and priority */ 07255 memcpy(chan->context, old_context, sizeof(chan->context)); 07256 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07257 chan->priority = old_priority; 07258 } else { 07259 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07260 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07261 } 07262 } else { 07263 /* Ask for an extension */ 07264 ast_test_suite_event_notify("PLAYBACK", "Message: vm-extension"); 07265 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07266 prompt_played++; 07267 if (res || prompt_played > 4) 07268 break; 07269 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07270 break; 07271 } 07272 07273 /* start all over if no username */ 07274 if (ast_strlen_zero(username)) 07275 continue; 07276 stringp = username; 07277 s = strsep(&stringp, "*"); 07278 /* start optimistic */ 07279 valid_extensions = 1; 07280 while (s) { 07281 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07282 int oldmsgs; 07283 int newmsgs; 07284 int capacity; 07285 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07286 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07287 /* Shouldn't happen, but allow trying another extension if it does */ 07288 res = ast_play_and_wait(chan, "pbx-invalid"); 07289 valid_extensions = 0; 07290 break; 07291 } 07292 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07293 if ((newmsgs + oldmsgs) >= capacity) { 07294 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07295 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07296 valid_extensions = 0; 07297 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07298 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07299 free_user(vmtmp); 07300 } 07301 inprocess_count(receiver->mailbox, receiver->context, -1); 07302 break; 07303 } 07304 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07305 } else { 07306 /* XXX Optimization for the future. When we encounter a single bad extension, 07307 * bailing out on all of the extensions may not be the way to go. We should 07308 * probably just bail on that single extension, then allow the user to enter 07309 * several more. XXX 07310 */ 07311 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07312 free_user(receiver); 07313 } 07314 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07315 /* "I am sorry, that's not a valid extension. Please try again." */ 07316 res = ast_play_and_wait(chan, "pbx-invalid"); 07317 valid_extensions = 0; 07318 break; 07319 } 07320 07321 /* play name if available, else play extension number */ 07322 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07323 RETRIEVE(fn, -1, s, receiver->context); 07324 if (ast_fileexists(fn, NULL, NULL) > 0) { 07325 res = ast_stream_and_wait(chan, fn, ecodes); 07326 if (res) { 07327 DISPOSE(fn, -1); 07328 return res; 07329 } 07330 } else { 07331 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07332 } 07333 DISPOSE(fn, -1); 07334 07335 s = strsep(&stringp, "*"); 07336 } 07337 /* break from the loop of reading the extensions */ 07338 if (valid_extensions) 07339 break; 07340 } 07341 /* check if we're clear to proceed */ 07342 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07343 return res; 07344 if (is_new_message == 1) { 07345 struct leave_vm_options leave_options; 07346 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07347 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07348 07349 /* Send VoiceMail */ 07350 memset(&leave_options, 0, sizeof(leave_options)); 07351 leave_options.record_gain = record_gain; 07352 cmd = leave_voicemail(chan, mailbox, &leave_options); 07353 } else { 07354 /* Forward VoiceMail */ 07355 long duration = 0; 07356 struct vm_state vmstmp; 07357 int copy_msg_result = 0; 07358 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07359 07360 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07361 07362 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07363 if (!cmd) { 07364 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07365 #ifdef IMAP_STORAGE 07366 int attach_user_voicemail; 07367 char *myserveremail = serveremail; 07368 07369 /* get destination mailbox */ 07370 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07371 if (!dstvms) { 07372 dstvms = create_vm_state_from_user(vmtmp); 07373 } 07374 if (dstvms) { 07375 init_mailstream(dstvms, 0); 07376 if (!dstvms->mailstream) { 07377 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07378 } else { 07379 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07380 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07381 } 07382 } else { 07383 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07384 } 07385 if (!ast_strlen_zero(vmtmp->serveremail)) 07386 myserveremail = vmtmp->serveremail; 07387 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07388 /* NULL category for IMAP storage */ 07389 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07390 dstvms->curbox, 07391 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07392 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07393 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07394 NULL, urgent_str); 07395 #else 07396 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07397 #endif 07398 saved_messages++; 07399 AST_LIST_REMOVE_CURRENT(list); 07400 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07401 free_user(vmtmp); 07402 if (res) 07403 break; 07404 } 07405 AST_LIST_TRAVERSE_SAFE_END; 07406 if (saved_messages > 0 && !copy_msg_result) { 07407 /* give confirmation that the message was saved */ 07408 /* commented out since we can't forward batches yet 07409 if (saved_messages == 1) 07410 res = ast_play_and_wait(chan, "vm-message"); 07411 else 07412 res = ast_play_and_wait(chan, "vm-messages"); 07413 if (!res) 07414 res = ast_play_and_wait(chan, "vm-saved"); */ 07415 #ifdef IMAP_STORAGE 07416 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07417 if (ast_strlen_zero(vmstmp.introfn)) 07418 #endif 07419 res = ast_play_and_wait(chan, "vm-msgsaved"); 07420 } 07421 #ifndef IMAP_STORAGE 07422 else { 07423 /* with IMAP, mailbox full warning played by imap_check_limits */ 07424 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07425 } 07426 /* Restore original message without prepended message if backup exists */ 07427 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07428 strcpy(textfile, msgfile); 07429 strcpy(backup, msgfile); 07430 strcpy(backup_textfile, msgfile); 07431 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07432 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07433 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07434 if (ast_fileexists(backup, NULL, NULL) > 0) { 07435 ast_filerename(backup, msgfile, NULL); 07436 rename(backup_textfile, textfile); 07437 } 07438 #endif 07439 } 07440 DISPOSE(dir, curmsg); 07441 #ifndef IMAP_STORAGE 07442 if (cmd) { /* assuming hangup, cleanup backup file */ 07443 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07444 strcpy(textfile, msgfile); 07445 strcpy(backup_textfile, msgfile); 07446 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07447 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07448 rename(backup_textfile, textfile); 07449 } 07450 #endif 07451 } 07452 07453 /* If anything failed above, we still have this list to free */ 07454 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07455 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07456 free_user(vmtmp); 07457 } 07458 return res ? res : cmd; 07459 }
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 11753 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().
11754 { 11755 struct ast_vm_user *current; 11756 AST_LIST_LOCK(&users); 11757 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11758 ast_set_flag(current, VM_ALLOCED); 11759 free_user(current); 11760 } 11761 AST_LIST_UNLOCK(&users); 11762 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11765 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().
11766 { 11767 struct vm_zone *zcur; 11768 AST_LIST_LOCK(&zones); 11769 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11770 free_zone(zcur); 11771 AST_LIST_UNLOCK(&zones); 11772 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5079 of file app_voicemail.c.
References ast_free.
05080 { 05081 ast_free(z); 05082 }
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 5035 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
05036 { 05037 struct ast_tm tm; 05038 struct timeval t = ast_tvnow(); 05039 05040 ast_localtime(&t, &tm, "UTC"); 05041 05042 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05043 }
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 6767 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().
06768 { 06769 int x; 06770 int d; 06771 char fn[PATH_MAX]; 06772 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06773 if (d) 06774 return d; 06775 for (x = start; x < 5; x++) { /* For all folders */ 06776 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06777 return d; 06778 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06779 if (d) 06780 return d; 06781 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06782 06783 /* The inbox folder can have its name changed under certain conditions 06784 * so this checks if the sound file exists for the inbox folder name and 06785 * if it doesn't, plays the default name instead. */ 06786 if (x == 0) { 06787 if (ast_fileexists(fn, NULL, NULL)) { 06788 d = vm_play_folder_name(chan, fn); 06789 } else { 06790 ast_verb(1, "failed to find %s\n", fn); 06791 d = vm_play_folder_name(chan, "vm-INBOX"); 06792 } 06793 } else { 06794 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06795 d = vm_play_folder_name(chan, fn); 06796 } 06797 06798 if (d) 06799 return d; 06800 d = ast_waitfordigit(chan, 500); 06801 if (d) 06802 return d; 06803 } 06804 06805 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06806 if (d) 06807 return d; 06808 d = ast_waitfordigit(chan, 4000); 06809 return d; 06810 }
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 6824 of file app_voicemail.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
Referenced by vm_execmain().
06825 { 06826 int res = 0; 06827 int loops = 0; 06828 06829 res = ast_play_and_wait(chan, fn); /* Folder name */ 06830 while (((res < '0') || (res > '9')) && 06831 (res != '#') && (res >= 0) && 06832 loops < 4) { 06833 res = get_folder(chan, 0); 06834 loops++; 06835 } 06836 if (loops == 4) { /* give up */ 06837 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06838 return '#'; 06839 } 06840 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06841 return res; 06842 }
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 11523 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().
11524 { 11525 unsigned int len; 11526 struct mwi_sub *mwi_sub; 11527 struct mwi_sub_task *p = datap; 11528 11529 len = sizeof(*mwi_sub); 11530 if (!ast_strlen_zero(p->mailbox)) 11531 len += strlen(p->mailbox); 11532 11533 if (!ast_strlen_zero(p->context)) 11534 len += strlen(p->context) + 1; /* Allow for seperator */ 11535 11536 if (!(mwi_sub = ast_calloc(1, len))) 11537 return -1; 11538 11539 mwi_sub->uniqueid = p->uniqueid; 11540 if (!ast_strlen_zero(p->mailbox)) 11541 strcpy(mwi_sub->mailbox, p->mailbox); 11542 11543 if (!ast_strlen_zero(p->context)) { 11544 strcat(mwi_sub->mailbox, "@"); 11545 strcat(mwi_sub->mailbox, p->context); 11546 } 11547 11548 AST_RWLIST_WRLOCK(&mwi_subs); 11549 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11550 AST_RWLIST_UNLOCK(&mwi_subs); 11551 ast_free((void *) p->mailbox); 11552 ast_free((void *) p->context); 11553 ast_free(p); 11554 poll_subscribed_mailbox(mwi_sub); 11555 return 0; 11556 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11501 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().
11502 { 11503 struct mwi_sub *mwi_sub; 11504 uint32_t *uniqueid = datap; 11505 11506 AST_RWLIST_WRLOCK(&mwi_subs); 11507 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11508 if (mwi_sub->uniqueid == *uniqueid) { 11509 AST_LIST_REMOVE_CURRENT(entry); 11510 break; 11511 } 11512 } 11513 AST_RWLIST_TRAVERSE_SAFE_END 11514 AST_RWLIST_UNLOCK(&mwi_subs); 11515 11516 if (mwi_sub) 11517 mwi_sub_destroy(mwi_sub); 11518 11519 ast_free(uniqueid); 11520 return 0; 11521 }
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 11276 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.
11277 { 11278 switch (cmd) { 11279 case CLI_INIT: 11280 e->command = "voicemail reload"; 11281 e->usage = 11282 "Usage: voicemail reload\n" 11283 " Reload voicemail configuration\n"; 11284 return NULL; 11285 case CLI_GENERATE: 11286 return NULL; 11287 } 11288 11289 if (a->argc != 2) 11290 return CLI_SHOWUSAGE; 11291 11292 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11293 load_config(1); 11294 11295 return CLI_SUCCESS; 11296 }
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 11164 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.
11165 { 11166 struct ast_vm_user *vmu; 11167 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11168 const char *context = NULL; 11169 int users_counter = 0; 11170 11171 switch (cmd) { 11172 case CLI_INIT: 11173 e->command = "voicemail show users"; 11174 e->usage = 11175 "Usage: voicemail show users [for <context>]\n" 11176 " Lists all mailboxes currently set up\n"; 11177 return NULL; 11178 case CLI_GENERATE: 11179 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11180 } 11181 11182 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11183 return CLI_SHOWUSAGE; 11184 if (a->argc == 5) { 11185 if (strcmp(a->argv[3],"for")) 11186 return CLI_SHOWUSAGE; 11187 context = a->argv[4]; 11188 } 11189 11190 if (ast_check_realtime("voicemail")) { 11191 if (!context) { 11192 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11193 return CLI_SHOWUSAGE; 11194 } 11195 return show_users_realtime(a->fd, context); 11196 } 11197 11198 AST_LIST_LOCK(&users); 11199 if (AST_LIST_EMPTY(&users)) { 11200 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11201 AST_LIST_UNLOCK(&users); 11202 return CLI_FAILURE; 11203 } 11204 if (!context) { 11205 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11206 } else { 11207 int count = 0; 11208 AST_LIST_TRAVERSE(&users, vmu, list) { 11209 if (!strcmp(context, vmu->context)) { 11210 count++; 11211 break; 11212 } 11213 } 11214 if (count) { 11215 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11216 } else { 11217 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11218 AST_LIST_UNLOCK(&users); 11219 return CLI_FAILURE; 11220 } 11221 } 11222 AST_LIST_TRAVERSE(&users, vmu, list) { 11223 int newmsgs = 0, oldmsgs = 0; 11224 char count[12], tmp[256] = ""; 11225 11226 if (!context || !strcmp(context, vmu->context)) { 11227 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11228 inboxcount(tmp, &newmsgs, &oldmsgs); 11229 snprintf(count, sizeof(count), "%d", newmsgs); 11230 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11231 users_counter++; 11232 } 11233 } 11234 AST_LIST_UNLOCK(&users); 11235 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11236 return CLI_SUCCESS; 11237 }
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 11240 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.
11241 { 11242 struct vm_zone *zone; 11243 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11244 char *res = CLI_SUCCESS; 11245 11246 switch (cmd) { 11247 case CLI_INIT: 11248 e->command = "voicemail show zones"; 11249 e->usage = 11250 "Usage: voicemail show zones\n" 11251 " Lists zone message formats\n"; 11252 return NULL; 11253 case CLI_GENERATE: 11254 return NULL; 11255 } 11256 11257 if (a->argc != 3) 11258 return CLI_SHOWUSAGE; 11259 11260 AST_LIST_LOCK(&zones); 11261 if (!AST_LIST_EMPTY(&zones)) { 11262 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11263 AST_LIST_TRAVERSE(&zones, zone, list) { 11264 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11265 } 11266 } else { 11267 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11268 res = CLI_FAILURE; 11269 } 11270 AST_LIST_UNLOCK(&zones); 11271 11272 return res; 11273 }
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 5423 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().
05424 { 05425 char tmp[256], *tmp2 = tmp, *box, *context; 05426 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05427 if (ast_strlen_zero(folder)) { 05428 folder = "INBOX"; 05429 } 05430 while ((box = strsep(&tmp2, ",&"))) { 05431 if ((context = strchr(box, '@'))) 05432 *context++ = '\0'; 05433 else 05434 context = "default"; 05435 if (__has_voicemail(context, box, folder, 1)) 05436 return 1; 05437 /* If we are checking INBOX, we should check Urgent as well */ 05438 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05439 return 1; 05440 } 05441 } 05442 return 0; 05443 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5505 of file app_voicemail.c.
References inboxcount2().
Referenced by forward_message(), handle_voicemail_show_users(), load_module(), and manager_list_voicemail_users().
05506 { 05507 int urgentmsgs = 0; 05508 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05509 if (newmsgs) { 05510 *newmsgs += urgentmsgs; 05511 } 05512 return res; 05513 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5446 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().
05447 { 05448 char tmp[256]; 05449 char *context; 05450 05451 /* If no mailbox, return immediately */ 05452 if (ast_strlen_zero(mailbox)) 05453 return 0; 05454 05455 if (newmsgs) 05456 *newmsgs = 0; 05457 if (oldmsgs) 05458 *oldmsgs = 0; 05459 if (urgentmsgs) 05460 *urgentmsgs = 0; 05461 05462 if (strchr(mailbox, ',')) { 05463 int tmpnew, tmpold, tmpurgent; 05464 char *mb, *cur; 05465 05466 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05467 mb = tmp; 05468 while ((cur = strsep(&mb, ", "))) { 05469 if (!ast_strlen_zero(cur)) { 05470 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05471 return -1; 05472 else { 05473 if (newmsgs) 05474 *newmsgs += tmpnew; 05475 if (oldmsgs) 05476 *oldmsgs += tmpold; 05477 if (urgentmsgs) 05478 *urgentmsgs += tmpurgent; 05479 } 05480 } 05481 } 05482 return 0; 05483 } 05484 05485 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05486 05487 if ((context = strchr(tmp, '@'))) 05488 *context++ = '\0'; 05489 else 05490 context = "default"; 05491 05492 if (newmsgs) 05493 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05494 if (oldmsgs) 05495 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05496 if (urgentmsgs) 05497 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05498 05499 return 0; 05500 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4205 of file app_voicemail.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by ast_eivr_getvariable(), ast_eivr_setvariable(), inchar(), netconsole(), sip_addheader(), and sip_removeheader().
04206 { 04207 int l; 04208 04209 if (bio->ateof) 04210 return 0; 04211 04212 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04213 if (ferror(fi)) 04214 return -1; 04215 04216 bio->ateof = 1; 04217 return 0; 04218 } 04219 04220 bio->iolen = l; 04221 bio->iocp = 0; 04222 04223 return 1; 04224 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4229 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
04230 { 04231 if (bio->iocp>=bio->iolen) { 04232 if (!inbuf(bio, fi)) 04233 return EOF; 04234 } 04235 04236 return bio->iobuf[bio->iocp++]; 04237 }
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 5045 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.
05046 { 05047 int res; 05048 char fn[PATH_MAX]; 05049 char dest[PATH_MAX]; 05050 05051 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05052 05053 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05054 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05055 return -1; 05056 } 05057 05058 RETRIEVE(fn, -1, ext, context); 05059 if (ast_fileexists(fn, NULL, NULL) > 0) { 05060 res = ast_stream_and_wait(chan, fn, ecodes); 05061 if (res) { 05062 DISPOSE(fn, -1); 05063 return res; 05064 } 05065 } else { 05066 /* Dispose just in case */ 05067 DISPOSE(fn, -1); 05068 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05069 if (res) 05070 return res; 05071 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 05072 if (res) 05073 return res; 05074 } 05075 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05076 return res; 05077 }
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 4024 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().
04025 { 04026 int x; 04027 unsigned char map[MAXMSGLIMIT] = ""; 04028 DIR *msgdir; 04029 struct dirent *msgdirent; 04030 int msgdirint; 04031 char extension[4]; 04032 int stopcount = 0; 04033 04034 /* Reading the entire directory into a file map scales better than 04035 * doing a stat repeatedly on a predicted sequence. I suspect this 04036 * is partially due to stat(2) internally doing a readdir(2) itself to 04037 * find each file. */ 04038 if (!(msgdir = opendir(dir))) { 04039 return -1; 04040 } 04041 04042 while ((msgdirent = readdir(msgdir))) { 04043 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04044 map[msgdirint] = 1; 04045 stopcount++; 04046 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04047 } 04048 } 04049 closedir(msgdir); 04050 04051 for (x = 0; x < vmu->maxmsg; x++) { 04052 if (map[x] == 1) { 04053 stopcount--; 04054 } else if (map[x] == 0 && !stopcount) { 04055 break; 04056 } 04057 } 04058 04059 return x - 1; 04060 }
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 5578 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, leave_vm_options::exitcontext, 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.
05579 { 05580 #ifdef IMAP_STORAGE 05581 int newmsgs, oldmsgs; 05582 #else 05583 char urgdir[PATH_MAX]; 05584 #endif 05585 char txtfile[PATH_MAX]; 05586 char tmptxtfile[PATH_MAX]; 05587 struct vm_state *vms = NULL; 05588 char callerid[256]; 05589 FILE *txt; 05590 char date[256]; 05591 int txtdes; 05592 int res = 0; 05593 int msgnum; 05594 int duration = 0; 05595 int sound_duration = 0; 05596 int ausemacro = 0; 05597 int ousemacro = 0; 05598 int ouseexten = 0; 05599 char tmpdur[16]; 05600 char priority[16]; 05601 char origtime[16]; 05602 char dir[PATH_MAX]; 05603 char tmpdir[PATH_MAX]; 05604 char fn[PATH_MAX]; 05605 char prefile[PATH_MAX] = ""; 05606 char tempfile[PATH_MAX] = ""; 05607 char ext_context[256] = ""; 05608 char fmt[80]; 05609 char *context; 05610 char ecodes[17] = "#"; 05611 struct ast_str *tmp = ast_str_create(16); 05612 char *tmpptr; 05613 struct ast_vm_user *vmu; 05614 struct ast_vm_user svm; 05615 const char *category = NULL; 05616 const char *code; 05617 const char *alldtmf = "0123456789ABCD*#"; 05618 char flag[80]; 05619 05620 if (!tmp) { 05621 return -1; 05622 } 05623 05624 ast_str_set(&tmp, 0, "%s", ext); 05625 ext = ast_str_buffer(tmp); 05626 if ((context = strchr(ext, '@'))) { 05627 *context++ = '\0'; 05628 tmpptr = strchr(context, '&'); 05629 } else { 05630 tmpptr = strchr(ext, '&'); 05631 } 05632 05633 if (tmpptr) 05634 *tmpptr++ = '\0'; 05635 05636 ast_channel_lock(chan); 05637 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05638 category = ast_strdupa(category); 05639 } 05640 ast_channel_unlock(chan); 05641 05642 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05643 ast_copy_string(flag, "Urgent", sizeof(flag)); 05644 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05645 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05646 } else { 05647 flag[0] = '\0'; 05648 } 05649 05650 ast_debug(3, "Before find_user\n"); 05651 if (!(vmu = find_user(&svm, context, ext))) { 05652 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05653 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05654 ast_free(tmp); 05655 return res; 05656 } 05657 /* Setup pre-file if appropriate */ 05658 if (strcmp(vmu->context, "default")) 05659 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05660 else 05661 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05662 05663 /* Set the path to the prefile. Will be one of 05664 VM_SPOOL_DIRcontext/ext/busy 05665 VM_SPOOL_DIRcontext/ext/unavail 05666 Depending on the flag set in options. 05667 */ 05668 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05669 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05670 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05671 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05672 } 05673 /* Set the path to the tmpfile as 05674 VM_SPOOL_DIR/context/ext/temp 05675 and attempt to create the folder structure. 05676 */ 05677 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05678 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05679 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05680 ast_free(tmp); 05681 return -1; 05682 } 05683 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05684 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05685 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05686 05687 DISPOSE(tempfile, -1); 05688 /* It's easier just to try to make it than to check for its existence */ 05689 #ifndef IMAP_STORAGE 05690 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05691 #else 05692 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05693 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05694 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05695 } 05696 #endif 05697 05698 /* Check current or macro-calling context for special extensions */ 05699 if (ast_test_flag(vmu, VM_OPERATOR)) { 05700 if (!ast_strlen_zero(vmu->exit)) { 05701 if (ast_exists_extension(chan, vmu->exit, "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 } 05706 } else if (ast_exists_extension(chan, chan->context, "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 ouseexten = 1; 05710 } else if (!ast_strlen_zero(chan->macrocontext) 05711 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05712 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05713 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05714 ousemacro = 1; 05715 } 05716 } 05717 05718 if (!ast_strlen_zero(vmu->exit)) { 05719 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05720 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05721 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05722 } 05723 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05724 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05725 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05726 } else if (!ast_strlen_zero(chan->macrocontext) 05727 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05728 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05729 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05730 ausemacro = 1; 05731 } 05732 05733 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05734 for (code = alldtmf; *code; code++) { 05735 char e[2] = ""; 05736 e[0] = *code; 05737 if (strchr(ecodes, e[0]) == NULL 05738 && ast_canmatch_extension(chan, 05739 (!ast_strlen_zero(options->exitcontext) ? options->exitcontext : chan->context), 05740 e, 1, S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05741 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05742 } 05743 } 05744 } 05745 05746 /* Play the beginning intro if desired */ 05747 if (!ast_strlen_zero(prefile)) { 05748 #ifdef ODBC_STORAGE 05749 int success = 05750 #endif 05751 RETRIEVE(prefile, -1, ext, context); 05752 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05753 if (ast_streamfile(chan, prefile, chan->language) > -1) 05754 res = ast_waitstream(chan, ecodes); 05755 #ifdef ODBC_STORAGE 05756 if (success == -1) { 05757 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05758 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05759 store_file(prefile, vmu->mailbox, vmu->context, -1); 05760 } 05761 #endif 05762 } else { 05763 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05764 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05765 } 05766 DISPOSE(prefile, -1); 05767 if (res < 0) { 05768 ast_debug(1, "Hang up during prefile playback\n"); 05769 free_user(vmu); 05770 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05771 ast_free(tmp); 05772 return -1; 05773 } 05774 } 05775 if (res == '#') { 05776 /* On a '#' we skip the instructions */ 05777 ast_set_flag(options, OPT_SILENT); 05778 res = 0; 05779 } 05780 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05781 if (vmu->maxmsg == 0) { 05782 if (option_debug > 2) 05783 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05784 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05785 goto leave_vm_out; 05786 } 05787 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05788 res = ast_stream_and_wait(chan, INTRO, ecodes); 05789 if (res == '#') { 05790 ast_set_flag(options, OPT_SILENT); 05791 res = 0; 05792 } 05793 } 05794 if (res > 0) 05795 ast_stopstream(chan); 05796 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05797 other than the operator -- an automated attendant or mailbox login for example */ 05798 if (res == '*') { 05799 chan->exten[0] = 'a'; 05800 chan->exten[1] = '\0'; 05801 if (!ast_strlen_zero(vmu->exit)) { 05802 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05803 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05804 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05805 } 05806 chan->priority = 0; 05807 free_user(vmu); 05808 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05809 ast_free(tmp); 05810 return 0; 05811 } 05812 05813 /* Check for a '0' here */ 05814 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05815 transfer: 05816 if (ouseexten || ousemacro) { 05817 chan->exten[0] = 'o'; 05818 chan->exten[1] = '\0'; 05819 if (!ast_strlen_zero(vmu->exit)) { 05820 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05821 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05822 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05823 } 05824 ast_play_and_wait(chan, "transfer"); 05825 chan->priority = 0; 05826 free_user(vmu); 05827 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05828 } 05829 ast_free(tmp); 05830 return OPERATOR_EXIT; 05831 } 05832 05833 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05834 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05835 if (!ast_strlen_zero(options->exitcontext)) { 05836 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05837 } 05838 free_user(vmu); 05839 ast_free(tmp); 05840 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05841 return res; 05842 } 05843 05844 if (res < 0) { 05845 free_user(vmu); 05846 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05847 ast_free(tmp); 05848 return -1; 05849 } 05850 /* The meat of recording the message... All the announcements and beeps have been played*/ 05851 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05852 if (!ast_strlen_zero(fmt)) { 05853 msgnum = 0; 05854 05855 #ifdef IMAP_STORAGE 05856 /* Is ext a mailbox? */ 05857 /* must open stream for this user to get info! */ 05858 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05859 if (res < 0) { 05860 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05861 ast_free(tmp); 05862 return -1; 05863 } 05864 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05865 /* It is possible under certain circumstances that inboxcount did not 05866 * create a vm_state when it was needed. This is a catchall which will 05867 * rarely be used. 05868 */ 05869 if (!(vms = create_vm_state_from_user(vmu))) { 05870 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05871 ast_free(tmp); 05872 return -1; 05873 } 05874 } 05875 vms->newmessages++; 05876 05877 /* here is a big difference! We add one to it later */ 05878 msgnum = newmsgs + oldmsgs; 05879 ast_debug(3, "Messagecount set to %d\n", msgnum); 05880 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05881 /* set variable for compatibility */ 05882 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05883 05884 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05885 goto leave_vm_out; 05886 } 05887 #else 05888 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05889 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05890 if (!res) 05891 res = ast_waitstream(chan, ""); 05892 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05893 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05894 inprocess_count(vmu->mailbox, vmu->context, -1); 05895 goto leave_vm_out; 05896 } 05897 05898 #endif 05899 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05900 txtdes = mkstemp(tmptxtfile); 05901 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05902 if (txtdes < 0) { 05903 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05904 if (!res) 05905 res = ast_waitstream(chan, ""); 05906 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05907 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05908 inprocess_count(vmu->mailbox, vmu->context, -1); 05909 goto leave_vm_out; 05910 } 05911 05912 /* Now play the beep once we have the message number for our next message. */ 05913 if (res >= 0) { 05914 /* Unless we're *really* silent, try to send the beep */ 05915 res = ast_stream_and_wait(chan, "beep", ""); 05916 } 05917 05918 /* Store information in real-time storage */ 05919 if (ast_check_realtime("voicemail_data")) { 05920 snprintf(priority, sizeof(priority), "%d", chan->priority); 05921 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05922 get_date(date, sizeof(date)); 05923 ast_callerid_merge(callerid, sizeof(callerid), 05924 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05925 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05926 "Unknown"); 05927 ast_store_realtime("voicemail_data", 05928 "origmailbox", ext, 05929 "context", chan->context, 05930 "macrocontext", chan->macrocontext, 05931 "exten", chan->exten, 05932 "priority", priority, 05933 "callerchan", chan->name, 05934 "callerid", callerid, 05935 "origdate", date, 05936 "origtime", origtime, 05937 "category", S_OR(category, ""), 05938 "filename", tmptxtfile, 05939 SENTINEL); 05940 } 05941 05942 /* Store information */ 05943 txt = fdopen(txtdes, "w+"); 05944 if (txt) { 05945 get_date(date, sizeof(date)); 05946 ast_callerid_merge(callerid, sizeof(callerid), 05947 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05948 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05949 "Unknown"); 05950 fprintf(txt, 05951 ";\n" 05952 "; Message Information file\n" 05953 ";\n" 05954 "[message]\n" 05955 "origmailbox=%s\n" 05956 "context=%s\n" 05957 "macrocontext=%s\n" 05958 "exten=%s\n" 05959 "rdnis=%s\n" 05960 "priority=%d\n" 05961 "callerchan=%s\n" 05962 "callerid=%s\n" 05963 "origdate=%s\n" 05964 "origtime=%ld\n" 05965 "category=%s\n", 05966 ext, 05967 chan->context, 05968 chan->macrocontext, 05969 chan->exten, 05970 S_COR(chan->redirecting.from.number.valid, 05971 chan->redirecting.from.number.str, "unknown"), 05972 chan->priority, 05973 chan->name, 05974 callerid, 05975 date, (long) time(NULL), 05976 category ? category : ""); 05977 } else { 05978 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05979 inprocess_count(vmu->mailbox, vmu->context, -1); 05980 if (ast_check_realtime("voicemail_data")) { 05981 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05982 } 05983 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05984 goto leave_vm_out; 05985 } 05986 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 05987 05988 if (txt) { 05989 fprintf(txt, "flag=%s\n", flag); 05990 if (sound_duration < vmu->minsecs) { 05991 fclose(txt); 05992 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 05993 ast_filedelete(tmptxtfile, NULL); 05994 unlink(tmptxtfile); 05995 if (ast_check_realtime("voicemail_data")) { 05996 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05997 } 05998 inprocess_count(vmu->mailbox, vmu->context, -1); 05999 } else { 06000 fprintf(txt, "duration=%d\n", duration); 06001 fclose(txt); 06002 if (vm_lock_path(dir)) { 06003 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 06004 /* Delete files */ 06005 ast_filedelete(tmptxtfile, NULL); 06006 unlink(tmptxtfile); 06007 inprocess_count(vmu->mailbox, vmu->context, -1); 06008 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06009 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06010 unlink(tmptxtfile); 06011 ast_unlock_path(dir); 06012 inprocess_count(vmu->mailbox, vmu->context, -1); 06013 if (ast_check_realtime("voicemail_data")) { 06014 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06015 } 06016 } else { 06017 #ifndef IMAP_STORAGE 06018 msgnum = last_message_index(vmu, dir) + 1; 06019 #endif 06020 make_file(fn, sizeof(fn), dir, msgnum); 06021 06022 /* assign a variable with the name of the voicemail file */ 06023 #ifndef IMAP_STORAGE 06024 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06025 #else 06026 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06027 #endif 06028 06029 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06030 ast_filerename(tmptxtfile, fn, NULL); 06031 rename(tmptxtfile, txtfile); 06032 inprocess_count(vmu->mailbox, vmu->context, -1); 06033 06034 /* Properly set permissions on voicemail text descriptor file. 06035 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06036 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06037 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06038 06039 ast_unlock_path(dir); 06040 if (ast_check_realtime("voicemail_data")) { 06041 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06042 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06043 } 06044 /* We must store the file first, before copying the message, because 06045 * ODBC storage does the entire copy with SQL. 06046 */ 06047 if (ast_fileexists(fn, NULL, NULL) > 0) { 06048 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06049 } 06050 06051 /* Are there to be more recipients of this message? */ 06052 while (tmpptr) { 06053 struct ast_vm_user recipu, *recip; 06054 char *exten, *cntx; 06055 06056 exten = strsep(&tmpptr, "&"); 06057 cntx = strchr(exten, '@'); 06058 if (cntx) { 06059 *cntx = '\0'; 06060 cntx++; 06061 } 06062 if ((recip = find_user(&recipu, cntx, exten))) { 06063 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06064 free_user(recip); 06065 } 06066 } 06067 #ifndef IMAP_STORAGE 06068 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06069 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06070 char sfn[PATH_MAX]; 06071 char dfn[PATH_MAX]; 06072 int x; 06073 /* It's easier just to try to make it than to check for its existence */ 06074 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06075 x = last_message_index(vmu, urgdir) + 1; 06076 make_file(sfn, sizeof(sfn), dir, msgnum); 06077 make_file(dfn, sizeof(dfn), urgdir, x); 06078 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06079 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06080 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06081 ast_copy_string(fn, dfn, sizeof(fn)); 06082 msgnum = x; 06083 } 06084 #endif 06085 /* Notification needs to happen after the copy, though. */ 06086 if (ast_fileexists(fn, NULL, NULL)) { 06087 #ifdef IMAP_STORAGE 06088 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06089 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06090 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06091 flag); 06092 #else 06093 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06094 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06095 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06096 flag); 06097 #endif 06098 } 06099 06100 /* Disposal needs to happen after the optional move and copy */ 06101 if (ast_fileexists(fn, NULL, NULL)) { 06102 DISPOSE(dir, msgnum); 06103 } 06104 } 06105 } 06106 } else { 06107 inprocess_count(vmu->mailbox, vmu->context, -1); 06108 } 06109 if (res == '0') { 06110 goto transfer; 06111 } else if (res > 0 && res != 't') 06112 res = 0; 06113 06114 if (sound_duration < vmu->minsecs) 06115 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06116 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06117 else 06118 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06119 } else 06120 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06121 leave_vm_out: 06122 free_user(vmu); 06123 06124 #ifdef IMAP_STORAGE 06125 /* expunge message - use UID Expunge if supported on IMAP server*/ 06126 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06127 if (expungeonhangup == 1) { 06128 ast_mutex_lock(&vms->lock); 06129 #ifdef HAVE_IMAP_TK2006 06130 if (LEVELUIDPLUS (vms->mailstream)) { 06131 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06132 } else 06133 #endif 06134 mail_expunge(vms->mailstream); 06135 ast_mutex_unlock(&vms->lock); 06136 } 06137 #endif 06138 06139 ast_free(tmp); 06140 return res; 06141 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11821 of file app_voicemail.c.
References actual_load_config(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_log(), ast_unload_realtime(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, and VOICEMAIL_CONFIG.
11822 { 11823 struct ast_config *cfg, *ucfg; 11824 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11825 int res; 11826 11827 ast_unload_realtime("voicemail"); 11828 ast_unload_realtime("voicemail_data"); 11829 11830 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11831 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11832 return 0; 11833 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11834 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11835 ucfg = NULL; 11836 } 11837 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11838 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11839 ast_config_destroy(ucfg); 11840 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11841 return 0; 11842 } 11843 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11844 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11845 return 0; 11846 } else { 11847 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11848 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11849 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11850 ucfg = NULL; 11851 } 11852 } 11853 11854 res = actual_load_config(reload, cfg, ucfg); 11855 11856 ast_config_destroy(cfg); 11857 ast_config_destroy(ucfg); 11858 11859 return res; 11860 }
static int load_module | ( | void | ) | [static] |
Definition at line 13121 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().
13122 { 13123 int res; 13124 my_umask = umask(0); 13125 umask(my_umask); 13126 13127 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13128 return AST_MODULE_LOAD_DECLINE; 13129 } 13130 13131 /* compute the location of the voicemail spool directory */ 13132 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13133 13134 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13135 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13136 } 13137 13138 if ((res = load_config(0))) 13139 return res; 13140 13141 res = ast_register_application_xml(app, vm_exec); 13142 res |= ast_register_application_xml(app2, vm_execmain); 13143 res |= ast_register_application_xml(app3, vm_box_exists); 13144 res |= ast_register_application_xml(app4, vmauthenticate); 13145 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13146 res |= ast_custom_function_register(&mailbox_exists_acf); 13147 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13148 #ifdef TEST_FRAMEWORK 13149 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13150 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13151 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13152 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13153 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13154 #endif 13155 13156 if (res) 13157 return res; 13158 13159 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13160 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13161 13162 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13163 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13164 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13165 13166 return res; 13167 }
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 4522 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(), ast_strftime_locale(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), charset, check_mime(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, emailbody, emaildateformat, ast_vm_user::emailsubject, emailsubject, ENDL, fromstring, ast_vm_user::fullname, globalflags, ast_vm_user::locale, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, ast_channel::name, prep_email_sub_vars(), ast_channel::priority, S_OR, strip_control_and_high(), VM_PBXSKIP, and vmu_tm().
Referenced by sendmail().
04523 { 04524 char date[256]; 04525 char host[MAXHOSTNAMELEN] = ""; 04526 char who[256]; 04527 char bound[256]; 04528 char dur[256]; 04529 struct ast_tm tm; 04530 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04531 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04532 char *greeting_attachment; 04533 char filename[256]; 04534 04535 if (!str1 || !str2) { 04536 ast_free(str1); 04537 ast_free(str2); 04538 return; 04539 } 04540 04541 if (cidnum) { 04542 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04543 } 04544 if (cidname) { 04545 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04546 } 04547 gethostname(host, sizeof(host) - 1); 04548 04549 if (strchr(srcemail, '@')) { 04550 ast_copy_string(who, srcemail, sizeof(who)); 04551 } else { 04552 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04553 } 04554 04555 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04556 if (greeting_attachment) { 04557 *greeting_attachment++ = '\0'; 04558 } 04559 04560 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04561 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04562 fprintf(p, "Date: %s" ENDL, date); 04563 04564 /* Set date format for voicemail mail */ 04565 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04566 04567 if (!ast_strlen_zero(fromstring)) { 04568 struct ast_channel *ast; 04569 if ((ast = ast_dummy_channel_alloc())) { 04570 char *ptr; 04571 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04572 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04573 04574 if (check_mime(ast_str_buffer(str1))) { 04575 int first_line = 1; 04576 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04577 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04578 *ptr = '\0'; 04579 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04580 first_line = 0; 04581 /* Substring is smaller, so this will never grow */ 04582 ast_str_set(&str2, 0, "%s", ptr + 1); 04583 } 04584 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04585 } else { 04586 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04587 } 04588 ast = ast_channel_unref(ast); 04589 } else { 04590 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04591 } 04592 } else { 04593 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04594 } 04595 04596 if (check_mime(vmu->fullname)) { 04597 int first_line = 1; 04598 char *ptr; 04599 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04600 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04601 *ptr = '\0'; 04602 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04603 first_line = 0; 04604 /* Substring is smaller, so this will never grow */ 04605 ast_str_set(&str2, 0, "%s", ptr + 1); 04606 } 04607 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04608 } else { 04609 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04610 } 04611 04612 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04613 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04614 struct ast_channel *ast; 04615 if ((ast = ast_dummy_channel_alloc())) { 04616 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04617 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04618 if (check_mime(ast_str_buffer(str1))) { 04619 int first_line = 1; 04620 char *ptr; 04621 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04622 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04623 *ptr = '\0'; 04624 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04625 first_line = 0; 04626 /* Substring is smaller, so this will never grow */ 04627 ast_str_set(&str2, 0, "%s", ptr + 1); 04628 } 04629 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04630 } else { 04631 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04632 } 04633 ast = ast_channel_unref(ast); 04634 } else { 04635 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04636 } 04637 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04638 if (ast_strlen_zero(flag)) { 04639 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04640 } else { 04641 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04642 } 04643 } else { 04644 if (ast_strlen_zero(flag)) { 04645 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04646 } else { 04647 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04648 } 04649 } 04650 04651 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04652 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04653 if (imap) { 04654 /* additional information needed for IMAP searching */ 04655 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04656 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04657 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04658 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04659 #ifdef IMAP_STORAGE 04660 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04661 #else 04662 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04663 #endif 04664 /* flag added for Urgent */ 04665 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04666 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04667 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04668 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04669 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04670 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04671 if (!ast_strlen_zero(category)) { 04672 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04673 } else { 04674 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04675 } 04676 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04677 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04678 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04679 } 04680 if (!ast_strlen_zero(cidnum)) { 04681 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04682 } 04683 if (!ast_strlen_zero(cidname)) { 04684 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04685 } 04686 fprintf(p, "MIME-Version: 1.0" ENDL); 04687 if (attach_user_voicemail) { 04688 /* Something unique. */ 04689 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04690 (int) getpid(), (unsigned int) ast_random()); 04691 04692 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04693 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04694 fprintf(p, "--%s" ENDL, bound); 04695 } 04696 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04697 if (emailbody || vmu->emailbody) { 04698 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04699 struct ast_channel *ast; 04700 if ((ast = ast_dummy_channel_alloc())) { 04701 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04702 ast_str_substitute_variables(&str1, 0, ast, e_body); 04703 #ifdef IMAP_STORAGE 04704 { 04705 /* Convert body to native line terminators for IMAP backend */ 04706 char *line = ast_str_buffer(str1), *next; 04707 do { 04708 /* Terminate line before outputting it to the file */ 04709 if ((next = strchr(line, '\n'))) { 04710 *next++ = '\0'; 04711 } 04712 fprintf(p, "%s" ENDL, line); 04713 line = next; 04714 } while (!ast_strlen_zero(line)); 04715 } 04716 #else 04717 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04718 #endif 04719 ast = ast_channel_unref(ast); 04720 } else { 04721 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04722 } 04723 } else if (msgnum > -1) { 04724 if (strcmp(vmu->mailbox, mailbox)) { 04725 /* Forwarded type */ 04726 struct ast_config *msg_cfg; 04727 const char *v; 04728 int inttime; 04729 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04730 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04731 /* Retrieve info from VM attribute file */ 04732 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04733 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04734 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04735 strcat(fromfile, ".txt"); 04736 } 04737 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04738 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04739 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04740 } 04741 04742 /* You might be tempted to do origdate, except that a) it's in the wrong 04743 * format, and b) it's missing for IMAP recordings. */ 04744 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04745 struct timeval tv = { inttime, }; 04746 struct ast_tm tm; 04747 ast_localtime(&tv, &tm, NULL); 04748 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04749 } 04750 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04751 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04752 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04753 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04754 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04755 date, origcallerid, origdate); 04756 ast_config_destroy(msg_cfg); 04757 } else { 04758 goto plain_message; 04759 } 04760 } else { 04761 plain_message: 04762 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04763 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04764 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04765 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04766 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04767 } 04768 } else { 04769 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04770 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04771 } 04772 04773 if (imap || attach_user_voicemail) { 04774 if (!ast_strlen_zero(attach2)) { 04775 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04776 ast_debug(5, "creating second attachment filename %s\n", filename); 04777 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04778 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04779 ast_debug(5, "creating attachment filename %s\n", filename); 04780 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04781 } else { 04782 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04783 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04784 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04785 } 04786 } 04787 ast_free(str1); 04788 ast_free(str2); 04789 }
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 11652 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().
11653 { 11654 struct ast_vm_user *vmu = NULL; 11655 const char *id = astman_get_header(m, "ActionID"); 11656 char actionid[128] = ""; 11657 11658 if (!ast_strlen_zero(id)) 11659 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11660 11661 AST_LIST_LOCK(&users); 11662 11663 if (AST_LIST_EMPTY(&users)) { 11664 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11665 AST_LIST_UNLOCK(&users); 11666 return RESULT_SUCCESS; 11667 } 11668 11669 astman_send_ack(s, m, "Voicemail user list will follow"); 11670 11671 AST_LIST_TRAVERSE(&users, vmu, list) { 11672 char dirname[256]; 11673 11674 #ifdef IMAP_STORAGE 11675 int new, old; 11676 inboxcount(vmu->mailbox, &new, &old); 11677 #endif 11678 11679 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11680 astman_append(s, 11681 "%s" 11682 "Event: VoicemailUserEntry\r\n" 11683 "VMContext: %s\r\n" 11684 "VoiceMailbox: %s\r\n" 11685 "Fullname: %s\r\n" 11686 "Email: %s\r\n" 11687 "Pager: %s\r\n" 11688 "ServerEmail: %s\r\n" 11689 "MailCommand: %s\r\n" 11690 "Language: %s\r\n" 11691 "TimeZone: %s\r\n" 11692 "Callback: %s\r\n" 11693 "Dialout: %s\r\n" 11694 "UniqueID: %s\r\n" 11695 "ExitContext: %s\r\n" 11696 "SayDurationMinimum: %d\r\n" 11697 "SayEnvelope: %s\r\n" 11698 "SayCID: %s\r\n" 11699 "AttachMessage: %s\r\n" 11700 "AttachmentFormat: %s\r\n" 11701 "DeleteMessage: %s\r\n" 11702 "VolumeGain: %.2f\r\n" 11703 "CanReview: %s\r\n" 11704 "CallOperator: %s\r\n" 11705 "MaxMessageCount: %d\r\n" 11706 "MaxMessageLength: %d\r\n" 11707 "NewMessageCount: %d\r\n" 11708 #ifdef IMAP_STORAGE 11709 "OldMessageCount: %d\r\n" 11710 "IMAPUser: %s\r\n" 11711 #endif 11712 "\r\n", 11713 actionid, 11714 vmu->context, 11715 vmu->mailbox, 11716 vmu->fullname, 11717 vmu->email, 11718 vmu->pager, 11719 vmu->serveremail, 11720 vmu->mailcmd, 11721 vmu->language, 11722 vmu->zonetag, 11723 vmu->callback, 11724 vmu->dialout, 11725 vmu->uniqueid, 11726 vmu->exit, 11727 vmu->saydurationm, 11728 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11729 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11730 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11731 vmu->attachfmt, 11732 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11733 vmu->volgain, 11734 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11735 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11736 vmu->maxmsg, 11737 vmu->maxsecs, 11738 #ifdef IMAP_STORAGE 11739 new, old, vmu->imapuser 11740 #else 11741 count_messages(vmu, dirname) 11742 #endif 11743 ); 11744 } 11745 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11746 11747 AST_LIST_UNLOCK(&users); 11748 11749 return RESULT_SUCCESS; 11750 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11473 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().
11474 { 11475 while (poll_thread_run) { 11476 struct timespec ts = { 0, }; 11477 struct timeval wait; 11478 11479 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11480 ts.tv_sec = wait.tv_sec; 11481 ts.tv_nsec = wait.tv_usec * 1000; 11482 11483 ast_mutex_lock(&poll_lock); 11484 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11485 ast_mutex_unlock(&poll_lock); 11486 11487 if (!poll_thread_run) 11488 break; 11489 11490 poll_subscribed_mailboxes(); 11491 } 11492 11493 return NULL; 11494 }
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 5372 of file app_voicemail.c.
References __has_voicemail().
Referenced by load_module().
05373 { 05374 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05375 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11496 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 11584 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().
11585 { 11586 struct mwi_sub_task *mwist; 11587 11588 if (ast_event_get_type(event) != AST_EVENT_SUB) 11589 return; 11590 11591 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11592 return; 11593 11594 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11595 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11596 return; 11597 } 11598 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11599 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11600 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11601 11602 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11603 ast_free(mwist); 11604 } 11605 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11558 of file app_voicemail.c.
References ast_calloc, ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_UNSUB, ast_free, ast_log(), ast_taskprocessor_push(), handle_unsubscribe(), LOG_ERROR, mwi_subscription_tps, and mwi_sub_task::uniqueid.
Referenced by start_poll_thread().
11559 { 11560 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11561 11562 if (!uniqueid) { 11563 ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); 11564 return; 11565 } 11566 11567 if (ast_event_get_type(event) != AST_EVENT_UNSUB) { 11568 ast_free(uniqueid); 11569 return; 11570 } 11571 11572 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { 11573 ast_free(uniqueid); 11574 return; 11575 } 11576 11577 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11578 *uniqueid = u; 11579 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11580 ast_free(uniqueid); 11581 } 11582 }
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 7055 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.
07056 { 07057 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07058 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07059 const char *category; 07060 char *myserveremail = serveremail; 07061 07062 ast_channel_lock(chan); 07063 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07064 category = ast_strdupa(category); 07065 } 07066 ast_channel_unlock(chan); 07067 07068 #ifndef IMAP_STORAGE 07069 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07070 #else 07071 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07072 #endif 07073 make_file(fn, sizeof(fn), todir, msgnum); 07074 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07075 07076 if (!ast_strlen_zero(vmu->attachfmt)) { 07077 if (strstr(fmt, vmu->attachfmt)) 07078 fmt = vmu->attachfmt; 07079 else 07080 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); 07081 } 07082 07083 /* Attach only the first format */ 07084 fmt = ast_strdupa(fmt); 07085 stringp = fmt; 07086 strsep(&stringp, "|"); 07087 07088 if (!ast_strlen_zero(vmu->serveremail)) 07089 myserveremail = vmu->serveremail; 07090 07091 if (!ast_strlen_zero(vmu->email)) { 07092 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07093 07094 if (attach_user_voicemail) 07095 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07096 07097 /* XXX possible imap issue, should category be NULL XXX */ 07098 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07099 07100 if (attach_user_voicemail) 07101 DISPOSE(todir, msgnum); 07102 } 07103 07104 if (!ast_strlen_zero(vmu->pager)) { 07105 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07106 } 07107 07108 if (ast_test_flag(vmu, VM_DELETE)) 07109 DELETE(todir, msgnum, fn, vmu); 07110 07111 /* Leave voicemail for someone */ 07112 if (ast_app_has_voicemail(ext_context, NULL)) 07113 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07114 07115 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07116 07117 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); 07118 run_externnotify(vmu->context, vmu->mailbox, flag); 07119 07120 #ifdef IMAP_STORAGE 07121 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07122 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07123 vm_imap_delete(NULL, vms->curmsg, vmu); 07124 vms->newmessages--; /* Fix new message count */ 07125 } 07126 #endif 07127 07128 return 0; 07129 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4242 of file app_voicemail.c.
References BASELINELEN, ENDL, and baseio::linelength.
Referenced by base_encode().
04243 { 04244 if (bio->linelength >= BASELINELEN) { 04245 if (fputs(ENDL, so) == EOF) { 04246 return -1; 04247 } 04248 04249 bio->linelength = 0; 04250 } 04251 04252 if (putc(((unsigned char) c), so) == EOF) { 04253 return -1; 04254 } 04255 04256 bio->linelength++; 04257 04258 return 1; 04259 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7904 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().
07905 { 07906 int count_msg, last_msg; 07907 07908 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07909 07910 /* Rename the member vmbox HERE so that we don't try to return before 07911 * we know what's going on. 07912 */ 07913 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07914 07915 /* Faster to make the directory than to check if it exists. */ 07916 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07917 07918 /* traverses directory using readdir (or select query for ODBC) */ 07919 count_msg = count_messages(vmu, vms->curdir); 07920 if (count_msg < 0) { 07921 return count_msg; 07922 } else { 07923 vms->lastmsg = count_msg - 1; 07924 } 07925 07926 if (vm_allocate_dh(vms, vmu, count_msg)) { 07927 return -1; 07928 } 07929 07930 /* 07931 The following test is needed in case sequencing gets messed up. 07932 There appears to be more than one way to mess up sequence, so 07933 we will not try to find all of the root causes--just fix it when 07934 detected. 07935 */ 07936 07937 if (vm_lock_path(vms->curdir)) { 07938 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07939 return ERROR_LOCK_PATH; 07940 } 07941 07942 /* for local storage, checks directory for messages up to maxmsg limit */ 07943 last_msg = last_message_index(vmu, vms->curdir); 07944 ast_unlock_path(vms->curdir); 07945 07946 if (last_msg < -1) { 07947 return last_msg; 07948 } else if (vms->lastmsg != last_msg) { 07949 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); 07950 resequence_mailbox(vmu, vms->curdir, count_msg); 07951 } 07952 07953 return 0; 07954 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7678 of file app_voicemail.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, 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().
07679 { 07680 int res = 0; 07681 char filename[256], *cid; 07682 const char *origtime, *context, *category, *duration, *flag; 07683 struct ast_config *msg_cfg; 07684 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07685 07686 vms->starting = 0; 07687 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07688 adsi_message(chan, vms); 07689 if (!vms->curmsg) { 07690 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07691 } else if (vms->curmsg == vms->lastmsg) { 07692 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07693 } 07694 07695 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07696 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07697 msg_cfg = ast_config_load(filename, config_flags); 07698 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07699 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07700 return 0; 07701 } 07702 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07703 07704 /* Play the word urgent if we are listening to urgent messages */ 07705 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07706 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07707 } 07708 07709 if (!res) { 07710 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07711 /* POLISH syntax */ 07712 if (!strncasecmp(chan->language, "pl", 2)) { 07713 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07714 int ten, one; 07715 char nextmsg[256]; 07716 ten = (vms->curmsg + 1) / 10; 07717 one = (vms->curmsg + 1) % 10; 07718 07719 if (vms->curmsg < 20) { 07720 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07721 res = wait_file2(chan, vms, nextmsg); 07722 } else { 07723 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07724 res = wait_file2(chan, vms, nextmsg); 07725 if (one > 0) { 07726 if (!res) { 07727 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07728 res = wait_file2(chan, vms, nextmsg); 07729 } 07730 } 07731 } 07732 } 07733 if (!res) 07734 res = wait_file2(chan, vms, "vm-message"); 07735 /* HEBREW syntax */ 07736 } else if (!strncasecmp(chan->language, "he", 2)) { 07737 if (!vms->curmsg) { 07738 res = wait_file2(chan, vms, "vm-message"); 07739 res = wait_file2(chan, vms, "vm-first"); 07740 } else if (vms->curmsg == vms->lastmsg) { 07741 res = wait_file2(chan, vms, "vm-message"); 07742 res = wait_file2(chan, vms, "vm-last"); 07743 } else { 07744 res = wait_file2(chan, vms, "vm-message"); 07745 res = wait_file2(chan, vms, "vm-number"); 07746 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07747 } 07748 /* VIETNAMESE syntax */ 07749 } else if (!strncasecmp(chan->language, "vi", 2)) { 07750 if (!vms->curmsg) { 07751 res = wait_file2(chan, vms, "vm-message"); 07752 res = wait_file2(chan, vms, "vm-first"); 07753 } else if (vms->curmsg == vms->lastmsg) { 07754 res = wait_file2(chan, vms, "vm-message"); 07755 res = wait_file2(chan, vms, "vm-last"); 07756 } else { 07757 res = wait_file2(chan, vms, "vm-message"); 07758 res = wait_file2(chan, vms, "vm-number"); 07759 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07760 } 07761 } else { 07762 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07763 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07764 } else { /* DEFAULT syntax */ 07765 res = wait_file2(chan, vms, "vm-message"); 07766 } 07767 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07768 if (!res) { 07769 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07770 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07771 } 07772 } 07773 } 07774 } 07775 07776 if (!msg_cfg) { 07777 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07778 return 0; 07779 } 07780 07781 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07782 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07783 DISPOSE(vms->curdir, vms->curmsg); 07784 ast_config_destroy(msg_cfg); 07785 return 0; 07786 } 07787 07788 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07789 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07790 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07791 07792 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07793 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07794 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07795 if (!res) { 07796 res = play_message_category(chan, category); 07797 } 07798 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07799 res = play_message_datetime(chan, vmu, origtime, filename); 07800 } 07801 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07802 res = play_message_callerid(chan, vms, cid, context, 0); 07803 } 07804 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07805 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07806 } 07807 /* Allow pressing '1' to skip envelope / callerid */ 07808 if (res == '1') { 07809 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07810 res = 0; 07811 } 07812 ast_config_destroy(msg_cfg); 07813 07814 if (!res) { 07815 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07816 #ifdef IMAP_STORAGE 07817 ast_mutex_lock(&vms->lock); 07818 #endif 07819 vms->heard[vms->curmsg] = 1; 07820 #ifdef IMAP_STORAGE 07821 ast_mutex_unlock(&vms->lock); 07822 /*IMAP storage stores any prepended message from a forward 07823 * as a separate file from the rest of the message 07824 */ 07825 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07826 wait_file(chan, vms, vms->introfn); 07827 } 07828 #endif 07829 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07830 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07831 res = 0; 07832 } 07833 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07834 } 07835 DISPOSE(vms->curdir, vms->curmsg); 07836 return res; 07837 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7564 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().
07565 { 07566 int res = 0; 07567 int i; 07568 char *callerid, *name; 07569 char prefile[PATH_MAX] = ""; 07570 07571 07572 /* If voicemail cid is not enabled, or we didn't get cid or context from 07573 * the attribute file, leave now. 07574 * 07575 * TODO Still need to change this so that if this function is called by the 07576 * message envelope (and someone is explicitly requesting to hear the CID), 07577 * it does not check to see if CID is enabled in the config file. 07578 */ 07579 if ((cid == NULL)||(context == NULL)) 07580 return res; 07581 07582 /* Strip off caller ID number from name */ 07583 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07584 ast_callerid_parse(cid, &name, &callerid); 07585 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07586 /* Check for internal contexts and only */ 07587 /* say extension when the call didn't come from an internal context in the list */ 07588 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07589 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07590 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07591 break; 07592 } 07593 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07594 if (!res) { 07595 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07596 if (!ast_strlen_zero(prefile)) { 07597 /* See if we can find a recorded name for this person instead of their extension number */ 07598 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07599 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07600 if (!callback) 07601 res = wait_file2(chan, vms, "vm-from"); 07602 res = ast_stream_and_wait(chan, prefile, ""); 07603 } else { 07604 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07605 /* Say "from extension" as one saying to sound smoother */ 07606 if (!callback) 07607 res = wait_file2(chan, vms, "vm-from-extension"); 07608 res = ast_say_digit_str(chan, callerid, "", chan->language); 07609 } 07610 } 07611 } 07612 } else if (!res) { 07613 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07614 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07615 if (!callback) 07616 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07617 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07618 } 07619 } else { 07620 /* Number unknown */ 07621 ast_debug(1, "VM-CID: From an unknown number\n"); 07622 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07623 res = wait_file2(chan, vms, "vm-unknown-caller"); 07624 } 07625 return res; 07626 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7475 of file app_voicemail.c.
References ast_log(), ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
07476 { 07477 int res = 0; 07478 07479 if (!ast_strlen_zero(category)) 07480 res = ast_play_and_wait(chan, category); 07481 07482 if (res) { 07483 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07484 res = 0; 07485 } 07486 07487 return res; 07488 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7490 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().
07491 { 07492 int res = 0; 07493 struct vm_zone *the_zone = NULL; 07494 time_t t; 07495 07496 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07497 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07498 return 0; 07499 } 07500 07501 /* Does this user have a timezone specified? */ 07502 if (!ast_strlen_zero(vmu->zonetag)) { 07503 /* Find the zone in the list */ 07504 struct vm_zone *z; 07505 AST_LIST_LOCK(&zones); 07506 AST_LIST_TRAVERSE(&zones, z, list) { 07507 if (!strcmp(z->name, vmu->zonetag)) { 07508 the_zone = z; 07509 break; 07510 } 07511 } 07512 AST_LIST_UNLOCK(&zones); 07513 } 07514 07515 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07516 #if 0 07517 /* Set the DIFF_* variables */ 07518 ast_localtime(&t, &time_now, NULL); 07519 tv_now = ast_tvnow(); 07520 ast_localtime(&tv_now, &time_then, NULL); 07521 07522 /* Day difference */ 07523 if (time_now.tm_year == time_then.tm_year) 07524 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07525 else 07526 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07527 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07528 07529 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07530 #endif 07531 if (the_zone) { 07532 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07533 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07534 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07535 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07536 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07537 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07538 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); 07539 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07540 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07541 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07542 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07543 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07544 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07545 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07546 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); 07547 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07548 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07549 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07550 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07551 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07552 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); 07553 } else { 07554 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07555 } 07556 #if 0 07557 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07558 #endif 07559 return res; 07560 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7628 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().
07629 { 07630 int res = 0; 07631 int durationm; 07632 int durations; 07633 /* Verify that we have a duration for the message */ 07634 if (duration == NULL) 07635 return res; 07636 07637 /* Convert from seconds to minutes */ 07638 durations = atoi(duration); 07639 durationm = (durations / 60); 07640 07641 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07642 07643 if ((!res) && (durationm >= minduration)) { 07644 res = wait_file2(chan, vms, "vm-duration"); 07645 07646 /* POLISH syntax */ 07647 if (!strncasecmp(chan->language, "pl", 2)) { 07648 div_t num = div(durationm, 10); 07649 07650 if (durationm == 1) { 07651 res = ast_play_and_wait(chan, "digits/1z"); 07652 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07653 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07654 if (num.rem == 2) { 07655 if (!num.quot) { 07656 res = ast_play_and_wait(chan, "digits/2-ie"); 07657 } else { 07658 res = say_and_wait(chan, durationm - 2 , chan->language); 07659 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07660 } 07661 } else { 07662 res = say_and_wait(chan, durationm, chan->language); 07663 } 07664 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07665 } else { 07666 res = say_and_wait(chan, durationm, chan->language); 07667 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07668 } 07669 /* DEFAULT syntax */ 07670 } else { 07671 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07672 res = wait_file2(chan, vms, "vm-minutes"); 07673 } 07674 } 07675 return res; 07676 }
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 13434 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.
13437 { 13438 /* Record message & let caller review or re-record it, or set options if applicable */ 13439 int res = 0; 13440 int cmd = 0; 13441 int max_attempts = 3; 13442 int attempts = 0; 13443 int recorded = 0; 13444 int msg_exists = 0; 13445 signed char zero_gain = 0; 13446 char tempfile[PATH_MAX]; 13447 char *acceptdtmf = "#"; 13448 char *canceldtmf = ""; 13449 int canceleddtmf = 0; 13450 13451 /* Note that urgent and private are for flagging messages as such in the future */ 13452 13453 /* barf if no pointer passed to store duration in */ 13454 if (duration == NULL) { 13455 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13456 return -1; 13457 } 13458 13459 if (!outsidecaller) 13460 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13461 else 13462 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13463 13464 cmd = '3'; /* Want to start by recording */ 13465 13466 while ((cmd >= 0) && (cmd != 't')) { 13467 switch (cmd) { 13468 case '1': 13469 if (!msg_exists) { 13470 /* In this case, 1 is to record a message */ 13471 cmd = '3'; 13472 break; 13473 } else { 13474 /* Otherwise 1 is to save the existing message */ 13475 ast_verb(3, "Saving message as is\n"); 13476 if (!outsidecaller) 13477 ast_filerename(tempfile, recordfile, NULL); 13478 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13479 if (!outsidecaller) { 13480 /* Saves to IMAP server only if imapgreeting=yes */ 13481 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13482 DISPOSE(recordfile, -1); 13483 } 13484 cmd = 't'; 13485 return res; 13486 } 13487 case '2': 13488 /* Review */ 13489 ast_verb(3, "Reviewing the message\n"); 13490 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13491 break; 13492 case '3': 13493 msg_exists = 0; 13494 /* Record */ 13495 if (recorded == 1) 13496 ast_verb(3, "Re-recording the message\n"); 13497 else 13498 ast_verb(3, "Recording the message\n"); 13499 13500 if (recorded && outsidecaller) { 13501 cmd = ast_play_and_wait(chan, INTRO); 13502 cmd = ast_play_and_wait(chan, "beep"); 13503 } 13504 recorded = 1; 13505 /* 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 */ 13506 if (record_gain) 13507 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13508 if (ast_test_flag(vmu, VM_OPERATOR)) 13509 canceldtmf = "0"; 13510 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13511 if (strchr(canceldtmf, cmd)) { 13512 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13513 canceleddtmf = 1; 13514 } 13515 if (record_gain) 13516 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13517 if (cmd == -1) { 13518 /* User has hung up, no options to give */ 13519 if (!outsidecaller) { 13520 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13521 ast_filedelete(tempfile, NULL); 13522 } 13523 return cmd; 13524 } 13525 if (cmd == '0') { 13526 break; 13527 } else if (cmd == '*') { 13528 break; 13529 #if 0 13530 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13531 /* Message is too short */ 13532 ast_verb(3, "Message too short\n"); 13533 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13534 cmd = ast_filedelete(tempfile, NULL); 13535 break; 13536 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13537 /* Message is all silence */ 13538 ast_verb(3, "Nothing recorded\n"); 13539 cmd = ast_filedelete(tempfile, NULL); 13540 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13541 if (!cmd) 13542 cmd = ast_play_and_wait(chan, "vm-speakup"); 13543 break; 13544 #endif 13545 } else { 13546 /* If all is well, a message exists */ 13547 msg_exists = 1; 13548 cmd = 0; 13549 } 13550 break; 13551 case '4': 13552 if (outsidecaller) { /* only mark vm messages */ 13553 /* Mark Urgent */ 13554 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13555 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13556 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13557 strcpy(flag, "Urgent"); 13558 } else if (flag) { 13559 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13560 res = ast_play_and_wait(chan, "vm-urgent-removed"); 13561 strcpy(flag, ""); 13562 } else { 13563 ast_play_and_wait(chan, "vm-sorry"); 13564 } 13565 cmd = 0; 13566 } else { 13567 cmd = ast_play_and_wait(chan, "vm-sorry"); 13568 } 13569 break; 13570 case '5': 13571 case '6': 13572 case '7': 13573 case '8': 13574 case '9': 13575 case '*': 13576 case '#': 13577 cmd = ast_play_and_wait(chan, "vm-sorry"); 13578 break; 13579 #if 0 13580 /* XXX Commented out for the moment because of the dangers of deleting 13581 a message while recording (can put the message numbers out of sync) */ 13582 case '*': 13583 /* Cancel recording, delete message, offer to take another message*/ 13584 cmd = ast_play_and_wait(chan, "vm-deleted"); 13585 cmd = ast_filedelete(tempfile, NULL); 13586 if (outsidecaller) { 13587 res = vm_exec(chan, NULL); 13588 return res; 13589 } 13590 else 13591 return 1; 13592 #endif 13593 case '0': 13594 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13595 cmd = ast_play_and_wait(chan, "vm-sorry"); 13596 break; 13597 } 13598 if (msg_exists || recorded) { 13599 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13600 if (!cmd) 13601 cmd = ast_waitfordigit(chan, 3000); 13602 if (cmd == '1') { 13603 ast_filerename(tempfile, recordfile, NULL); 13604 ast_play_and_wait(chan, "vm-msgsaved"); 13605 cmd = '0'; 13606 } else if (cmd == '4') { 13607 if (flag) { 13608 ast_play_and_wait(chan, "vm-marked-urgent"); 13609 strcpy(flag, "Urgent"); 13610 } 13611 ast_play_and_wait(chan, "vm-msgsaved"); 13612 cmd = '0'; 13613 } else { 13614 ast_play_and_wait(chan, "vm-deleted"); 13615 DELETE(tempfile, -1, tempfile, vmu); 13616 cmd = '0'; 13617 } 13618 } 13619 return cmd; 13620 default: 13621 /* If the caller is an ouside caller, and the review option is enabled, 13622 allow them to review the message, but let the owner of the box review 13623 their OGM's */ 13624 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13625 return cmd; 13626 if (msg_exists) { 13627 cmd = ast_play_and_wait(chan, "vm-review"); 13628 if (!cmd && outsidecaller) { 13629 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13630 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13631 } else if (flag) { 13632 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13633 } 13634 } 13635 } else { 13636 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13637 if (!cmd) 13638 cmd = ast_waitfordigit(chan, 600); 13639 } 13640 13641 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13642 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13643 if (!cmd) 13644 cmd = ast_waitfordigit(chan, 600); 13645 } 13646 #if 0 13647 if (!cmd) 13648 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13649 #endif 13650 if (!cmd) 13651 cmd = ast_waitfordigit(chan, 6000); 13652 if (!cmd) { 13653 attempts++; 13654 } 13655 if (attempts > max_attempts) { 13656 cmd = 't'; 13657 } 13658 } 13659 } 13660 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13661 /* Hang up or timeout, so delete the recording. */ 13662 ast_filedelete(tempfile, NULL); 13663 } 13664 13665 if (cmd != 't' && outsidecaller) 13666 ast_play_and_wait(chan, "vm-goodbye"); 13667 13668 return cmd; 13669 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11445 of file app_voicemail.c.
References inboxcount2(), mwi_sub, queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11446 { 11447 int new = 0, old = 0, urgent = 0; 11448 11449 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11450 11451 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11452 mwi_sub->old_urgent = urgent; 11453 mwi_sub->old_new = new; 11454 mwi_sub->old_old = old; 11455 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11456 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11457 } 11458 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11460 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().
11461 { 11462 struct mwi_sub *mwi_sub; 11463 11464 AST_RWLIST_RDLOCK(&mwi_subs); 11465 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11466 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11467 poll_subscribed_mailbox(mwi_sub); 11468 } 11469 } 11470 AST_RWLIST_UNLOCK(&mwi_subs); 11471 }
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 4330 of file app_voicemail.c.
References ast_callerid_merge(), ast_callerid_split(), ast_config_destroy(), ast_config_load, ast_localtime(), ast_log(), ast_strdupa, ast_strftime_locale(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, emaildateformat, ast_vm_user::fullname, ast_vm_user::locale, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, pbx_builtin_setvar_helper(), and S_OR.
04331 { 04332 char callerid[256]; 04333 char num[12]; 04334 char fromdir[256], fromfile[256]; 04335 struct ast_config *msg_cfg; 04336 const char *origcallerid, *origtime; 04337 char origcidname[80], origcidnum[80], origdate[80]; 04338 int inttime; 04339 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04340 04341 /* Prepare variables for substitution in email body and subject */ 04342 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04343 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04344 snprintf(num, sizeof(num), "%d", msgnum); 04345 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04346 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04347 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04348 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04349 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04350 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04351 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04352 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04353 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04354 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04355 04356 /* Retrieve info from VM attribute file */ 04357 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04358 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04359 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04360 strcat(fromfile, ".txt"); 04361 } 04362 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04363 if (option_debug > 0) { 04364 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04365 } 04366 return; 04367 } 04368 04369 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04370 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04371 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04372 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04373 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04374 } 04375 04376 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04377 struct timeval tv = { inttime, }; 04378 struct ast_tm tm; 04379 ast_localtime(&tv, &tm, NULL); 04380 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04381 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04382 } 04383 ast_config_destroy(msg_cfg); 04384 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 7018 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().
07019 { 07020 struct ast_event *event; 07021 char *mailbox, *context; 07022 07023 /* Strip off @default */ 07024 context = mailbox = ast_strdupa(box); 07025 strsep(&context, "@"); 07026 if (ast_strlen_zero(context)) 07027 context = "default"; 07028 07029 if (!(event = ast_event_new(AST_EVENT_MWI, 07030 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 07031 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 07032 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 07033 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 07034 AST_EVENT_IE_END))) { 07035 return; 07036 } 07037 07038 ast_event_queue_and_cache(event); 07039 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12551 of file app_voicemail.c.
References ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), and LOG_NOTICE.
Referenced by actual_load_config(), and append_mailbox().
12551 { 12552 struct ast_config *pwconf; 12553 struct ast_flags config_flags = { 0 }; 12554 12555 pwconf = ast_config_load(secretfn, config_flags); 12556 if (pwconf) { 12557 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12558 if (val) { 12559 ast_copy_string(password, val, passwordlen); 12560 ast_config_destroy(pwconf); 12561 return; 12562 } 12563 ast_config_destroy(pwconf); 12564 } 12565 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12566 }
static int reload | ( | void | ) | [static] |
Definition at line 13081 of file app_voicemail.c.
References load_config().
13082 { 13083 return load_config(1); 13084 }
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 4000 of file app_voicemail.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
04001 { 04002 char stxt[PATH_MAX]; 04003 char dtxt[PATH_MAX]; 04004 ast_filerename(sfn, dfn, NULL); 04005 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 04006 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 04007 if (ast_check_realtime("voicemail_data")) { 04008 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 04009 } 04010 rename(stxt, dtxt); 04011 }
static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6144 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().
06145 { 06146 /* we know the actual number of messages, so stop process when number is hit */ 06147 06148 int x, dest; 06149 char sfn[PATH_MAX]; 06150 char dfn[PATH_MAX]; 06151 06152 if (vm_lock_path(dir)) { 06153 return ERROR_LOCK_PATH; 06154 } 06155 06156 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06157 make_file(sfn, sizeof(sfn), dir, x); 06158 if (EXISTS(dir, x, sfn, NULL)) { 06159 06160 if (x != dest) { 06161 make_file(dfn, sizeof(dfn), dir, dest); 06162 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06163 } 06164 06165 dest++; 06166 } 06167 } 06168 ast_unlock_path(dir); 06169 06170 return dest; 06171 }
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 5515 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.
05516 { 05517 char arguments[255]; 05518 char ext_context[256] = ""; 05519 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05520 struct ast_smdi_mwi_message *mwi_msg; 05521 05522 if (!ast_strlen_zero(context)) 05523 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05524 else 05525 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05526 05527 if (smdi_iface) { 05528 if (ast_app_has_voicemail(ext_context, NULL)) 05529 ast_smdi_mwi_set(smdi_iface, extension); 05530 else 05531 ast_smdi_mwi_unset(smdi_iface, extension); 05532 05533 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05534 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05535 if (!strncmp(mwi_msg->cause, "INV", 3)) 05536 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05537 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05538 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05539 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05540 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05541 } else { 05542 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05543 } 05544 } 05545 05546 if (!ast_strlen_zero(externnotify)) { 05547 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05548 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05549 } else { 05550 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05551 ast_debug(1, "Executing %s\n", arguments); 05552 ast_safe_system(arguments); 05553 } 05554 } 05555 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6181 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().
06182 { 06183 #ifdef IMAP_STORAGE 06184 /* we must use mbox(x) folder names, and copy the message there */ 06185 /* simple. huh? */ 06186 char sequence[10]; 06187 char mailbox[256]; 06188 int res; 06189 06190 /* get the real IMAP message number for this message */ 06191 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06192 06193 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06194 ast_mutex_lock(&vms->lock); 06195 /* if save to Old folder, put in INBOX as read */ 06196 if (box == OLD_FOLDER) { 06197 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06198 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06199 } else if (box == NEW_FOLDER) { 06200 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06201 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06202 } 06203 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06204 ast_mutex_unlock(&vms->lock); 06205 return 0; 06206 } 06207 /* Create the folder if it don't exist */ 06208 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06209 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06210 if (mail_create(vms->mailstream, mailbox) == NIL) 06211 ast_debug(5, "Folder exists.\n"); 06212 else 06213 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06214 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06215 ast_mutex_unlock(&vms->lock); 06216 return res; 06217 #else 06218 char *dir = vms->curdir; 06219 char *username = vms->username; 06220 char *context = vmu->context; 06221 char sfn[PATH_MAX]; 06222 char dfn[PATH_MAX]; 06223 char ddir[PATH_MAX]; 06224 const char *dbox = mbox(vmu, box); 06225 int x, i; 06226 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06227 06228 if (vm_lock_path(ddir)) 06229 return ERROR_LOCK_PATH; 06230 06231 x = last_message_index(vmu, ddir) + 1; 06232 06233 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06234 x--; 06235 for (i = 1; i <= x; i++) { 06236 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06237 make_file(sfn, sizeof(sfn), ddir, i); 06238 make_file(dfn, sizeof(dfn), ddir, i - 1); 06239 if (EXISTS(ddir, i, sfn, NULL)) { 06240 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06241 } else 06242 break; 06243 } 06244 } else { 06245 if (x >= vmu->maxmsg) { 06246 ast_unlock_path(ddir); 06247 return -1; 06248 } 06249 } 06250 make_file(sfn, sizeof(sfn), dir, msg); 06251 make_file(dfn, sizeof(dfn), ddir, x); 06252 if (strcmp(sfn, dfn)) { 06253 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06254 } 06255 ast_unlock_path(ddir); 06256 #endif 06257 return 0; 06258 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6174 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().
06175 { 06176 int d; 06177 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06178 return d; 06179 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12537 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().
12538 { 12539 int res = -1; 12540 char dir[PATH_MAX]; 12541 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12542 ast_debug(2, "About to try retrieving name file %s\n", dir); 12543 RETRIEVE(dir, -1, mailbox, context); 12544 if (ast_fileexists(dir, NULL, NULL)) { 12545 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12546 } 12547 DISPOSE(dir, -1); 12548 return res; 12549 }
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 4845 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().
04846 { 04847 FILE *p = NULL; 04848 char tmp[80] = "/tmp/astmail-XXXXXX"; 04849 char tmp2[256]; 04850 char *stringp; 04851 04852 if (vmu && ast_strlen_zero(vmu->email)) { 04853 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04854 return(0); 04855 } 04856 04857 /* Mail only the first format */ 04858 format = ast_strdupa(format); 04859 stringp = format; 04860 strsep(&stringp, "|"); 04861 04862 if (!strcmp(format, "wav49")) 04863 format = "WAV"; 04864 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)); 04865 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04866 command hangs */ 04867 if ((p = vm_mkftemp(tmp)) == NULL) { 04868 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04869 return -1; 04870 } else { 04871 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04872 fclose(p); 04873 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04874 ast_safe_system(tmp2); 04875 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04876 } 04877 return 0; 04878 }
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 4880 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(), 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().
04881 { 04882 char enc_cidnum[256], enc_cidname[256]; 04883 char date[256]; 04884 char host[MAXHOSTNAMELEN] = ""; 04885 char who[256]; 04886 char dur[PATH_MAX]; 04887 char tmp[80] = "/tmp/astmail-XXXXXX"; 04888 char tmp2[PATH_MAX]; 04889 struct ast_tm tm; 04890 FILE *p; 04891 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04892 04893 if (!str1 || !str2) { 04894 ast_free(str1); 04895 ast_free(str2); 04896 return -1; 04897 } 04898 04899 if (cidnum) { 04900 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04901 } 04902 if (cidname) { 04903 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04904 } 04905 04906 if ((p = vm_mkftemp(tmp)) == NULL) { 04907 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04908 ast_free(str1); 04909 ast_free(str2); 04910 return -1; 04911 } 04912 gethostname(host, sizeof(host)-1); 04913 if (strchr(srcemail, '@')) { 04914 ast_copy_string(who, srcemail, sizeof(who)); 04915 } else { 04916 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04917 } 04918 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04919 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04920 fprintf(p, "Date: %s\n", date); 04921 04922 /* Reformat for custom pager format */ 04923 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04924 04925 if (!ast_strlen_zero(pagerfromstring)) { 04926 struct ast_channel *ast; 04927 if ((ast = ast_dummy_channel_alloc())) { 04928 char *ptr; 04929 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04930 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04931 04932 if (check_mime(ast_str_buffer(str1))) { 04933 int first_line = 1; 04934 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04935 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04936 *ptr = '\0'; 04937 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04938 first_line = 0; 04939 /* Substring is smaller, so this will never grow */ 04940 ast_str_set(&str2, 0, "%s", ptr + 1); 04941 } 04942 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04943 } else { 04944 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04945 } 04946 ast = ast_channel_unref(ast); 04947 } else { 04948 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04949 } 04950 } else { 04951 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04952 } 04953 04954 if (check_mime(vmu->fullname)) { 04955 int first_line = 1; 04956 char *ptr; 04957 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04958 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04959 *ptr = '\0'; 04960 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04961 first_line = 0; 04962 /* Substring is smaller, so this will never grow */ 04963 ast_str_set(&str2, 0, "%s", ptr + 1); 04964 } 04965 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04966 } else { 04967 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04968 } 04969 04970 if (!ast_strlen_zero(pagersubject)) { 04971 struct ast_channel *ast; 04972 if ((ast = ast_dummy_channel_alloc())) { 04973 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04974 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 04975 if (check_mime(ast_str_buffer(str1))) { 04976 int first_line = 1; 04977 char *ptr; 04978 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04979 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04980 *ptr = '\0'; 04981 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04982 first_line = 0; 04983 /* Substring is smaller, so this will never grow */ 04984 ast_str_set(&str2, 0, "%s", ptr + 1); 04985 } 04986 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04987 } else { 04988 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04989 } 04990 ast = ast_channel_unref(ast); 04991 } else { 04992 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04993 } 04994 } else { 04995 if (ast_strlen_zero(flag)) { 04996 fprintf(p, "Subject: New VM\n\n"); 04997 } else { 04998 fprintf(p, "Subject: New %s VM\n\n", flag); 04999 } 05000 } 05001 05002 if (pagerbody) { 05003 struct ast_channel *ast; 05004 if ((ast = ast_dummy_channel_alloc())) { 05005 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05006 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 05007 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 05008 ast = ast_channel_unref(ast); 05009 } else { 05010 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05011 } 05012 } else { 05013 fprintf(p, "New %s long %s msg in box %s\n" 05014 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 05015 } 05016 05017 fclose(p); 05018 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 05019 ast_safe_system(tmp2); 05020 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 05021 ast_free(str1); 05022 ast_free(str2); 05023 return 0; 05024 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 11100 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().
11101 { 11102 struct ast_config *cfg; 11103 const char *cat = NULL; 11104 11105 if (!(cfg = ast_load_realtime_multientry("voicemail", 11106 "context", context, SENTINEL))) { 11107 return CLI_FAILURE; 11108 } 11109 11110 ast_cli(fd, 11111 "\n" 11112 "=============================================================\n" 11113 "=== Configured Voicemail Users ==============================\n" 11114 "=============================================================\n" 11115 "===\n"); 11116 11117 while ((cat = ast_category_browse(cfg, cat))) { 11118 struct ast_variable *var = NULL; 11119 ast_cli(fd, 11120 "=== Mailbox ...\n" 11121 "===\n"); 11122 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11123 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11124 ast_cli(fd, 11125 "===\n" 11126 "=== ---------------------------------------------------------\n" 11127 "===\n"); 11128 } 11129 11130 ast_cli(fd, 11131 "=============================================================\n" 11132 "\n"); 11133 11134 ast_config_destroy(cfg); 11135 11136 return CLI_SUCCESS; 11137 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11607 of file app_voicemail.c.
References AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_report_subs(), AST_EVENT_SUB, ast_event_subscribe(), AST_EVENT_UNSUB, ast_log(), ast_pthread_create, LOG_ERROR, mb_poll_thread(), mwi_sub_event_cb(), mwi_sub_sub, mwi_unsub_event_cb(), mwi_unsub_sub, poll_thread, and poll_thread_run.
Referenced by actual_load_config().
11608 { 11609 int errcode; 11610 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11611 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11612 AST_EVENT_IE_END); 11613 11614 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11615 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11616 AST_EVENT_IE_END); 11617 11618 if (mwi_sub_sub) 11619 ast_event_report_subs(mwi_sub_sub); 11620 11621 poll_thread_run = 1; 11622 11623 if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) { 11624 ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode)); 11625 } 11626 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11628 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().
11629 { 11630 poll_thread_run = 0; 11631 11632 if (mwi_sub_sub) { 11633 ast_event_unsubscribe(mwi_sub_sub); 11634 mwi_sub_sub = NULL; 11635 } 11636 11637 if (mwi_unsub_sub) { 11638 ast_event_unsubscribe(mwi_unsub_sub); 11639 mwi_unsub_sub = NULL; 11640 } 11641 11642 ast_mutex_lock(&poll_lock); 11643 ast_cond_signal(&poll_cond); 11644 ast_mutex_unlock(&poll_lock); 11645 11646 pthread_join(poll_thread, NULL); 11647 11648 poll_thread = AST_PTHREADT_NULL; 11649 }
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 11774 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().
11775 { 11776 char *current; 11777 11778 /* Add 16 for fudge factor */ 11779 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11780 11781 ast_str_reset(str); 11782 11783 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11784 for (current = (char *) value; *current; current++) { 11785 if (*current == '\\') { 11786 current++; 11787 if (!*current) { 11788 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11789 break; 11790 } 11791 switch (*current) { 11792 case '\\': 11793 ast_str_append(&str, 0, "\\"); 11794 break; 11795 case 'r': 11796 ast_str_append(&str, 0, "\r"); 11797 break; 11798 case 'n': 11799 #ifdef IMAP_STORAGE 11800 if (!str->used || str->str[str->used - 1] != '\r') { 11801 ast_str_append(&str, 0, "\r"); 11802 } 11803 #endif 11804 ast_str_append(&str, 0, "\n"); 11805 break; 11806 case 't': 11807 ast_str_append(&str, 0, "\t"); 11808 break; 11809 default: 11810 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11811 break; 11812 } 11813 } else { 11814 ast_str_append(&str, 0, "%c", *current); 11815 } 11816 } 11817 11818 return ast_str_buffer(str); 11819 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13086 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().
13087 { 13088 int res; 13089 13090 res = ast_unregister_application(app); 13091 res |= ast_unregister_application(app2); 13092 res |= ast_unregister_application(app3); 13093 res |= ast_unregister_application(app4); 13094 res |= ast_unregister_application(sayname_app); 13095 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13096 res |= ast_manager_unregister("VoicemailUsersList"); 13097 res |= ast_data_unregister(NULL); 13098 #ifdef TEST_FRAMEWORK 13099 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13100 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13101 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13102 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13103 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13104 #endif 13105 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13106 ast_uninstall_vm_functions(); 13107 ao2_ref(inprocess_container, -1); 13108 13109 if (poll_thread != AST_PTHREADT_NULL) 13110 stop_poll_thread(); 13111 13112 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13113 ast_unload_realtime("voicemail"); 13114 ast_unload_realtime("voicemail_data"); 13115 13116 free_vm_users(); 13117 free_vm_zones(); 13118 return res; 13119 }
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_free, 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 01754 /* remove old allocation */ 01755 if (vms->deleted) { 01756 ast_free(vms->deleted); 01757 vms->deleted = NULL; 01758 } 01759 if (vms->heard) { 01760 ast_free(vms->heard); 01761 vms->heard = NULL; 01762 } 01763 vms->dh_arraysize = 0; 01764 01765 if (arraysize > 0) { 01766 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01767 return -1; 01768 } 01769 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01770 ast_free(vms->deleted); 01771 vms->deleted = NULL; 01772 return -1; 01773 } 01774 vms->dh_arraysize = arraysize; 01775 } 01776 01777 return 0; 01778 }
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 9776 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().
09779 { 09780 int useadsi = 0, valid = 0, logretries = 0; 09781 char password[AST_MAX_EXTENSION]="", *passptr; 09782 struct ast_vm_user vmus, *vmu = NULL; 09783 09784 /* If ADSI is supported, setup login screen */ 09785 adsi_begin(chan, &useadsi); 09786 if (!skipuser && useadsi) 09787 adsi_login(chan); 09788 ast_test_suite_event_notify("PLAYBACK", "Message: vm-login"); 09789 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09790 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09791 return -1; 09792 } 09793 09794 /* Authenticate them and get their mailbox/password */ 09795 09796 while (!valid && (logretries < max_logins)) { 09797 /* Prompt for, and read in the username */ 09798 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09799 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09800 return -1; 09801 } 09802 if (ast_strlen_zero(mailbox)) { 09803 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09804 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09805 } else { 09806 ast_verb(3, "Username not entered\n"); 09807 return -1; 09808 } 09809 } else if (mailbox[0] == '*') { 09810 /* user entered '*' */ 09811 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09812 if (ast_exists_extension(chan, chan->context, "a", 1, 09813 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09814 return -1; 09815 } 09816 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09817 mailbox[0] = '\0'; 09818 } 09819 09820 if (useadsi) 09821 adsi_password(chan); 09822 09823 if (!ast_strlen_zero(prefix)) { 09824 char fullusername[80] = ""; 09825 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09826 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09827 ast_copy_string(mailbox, fullusername, mailbox_size); 09828 } 09829 09830 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09831 vmu = find_user(&vmus, context, mailbox); 09832 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09833 /* saved password is blank, so don't bother asking */ 09834 password[0] = '\0'; 09835 } else { 09836 ast_test_suite_event_notify("PLAYBACK", "Message: %s", vm_password); 09837 if (ast_streamfile(chan, vm_password, chan->language)) { 09838 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09839 return -1; 09840 } 09841 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09842 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09843 return -1; 09844 } else if (password[0] == '*') { 09845 /* user entered '*' */ 09846 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09847 if (ast_exists_extension(chan, chan->context, "a", 1, 09848 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09849 mailbox[0] = '*'; 09850 return -1; 09851 } 09852 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09853 mailbox[0] = '\0'; 09854 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09855 vmu = NULL; 09856 } 09857 } 09858 09859 if (vmu) { 09860 passptr = vmu->password; 09861 if (passptr[0] == '-') passptr++; 09862 } 09863 if (vmu && !strcmp(passptr, password)) 09864 valid++; 09865 else { 09866 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09867 if (!ast_strlen_zero(prefix)) 09868 mailbox[0] = '\0'; 09869 } 09870 logretries++; 09871 if (!valid) { 09872 if (skipuser || logretries >= max_logins) { 09873 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect"); 09874 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09875 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09876 return -1; 09877 } 09878 } else { 09879 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect-mailbox"); 09880 if (useadsi) 09881 adsi_login(chan); 09882 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09883 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09884 return -1; 09885 } 09886 } 09887 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09888 return -1; 09889 } 09890 } 09891 if (!valid && (logretries >= max_logins)) { 09892 ast_stopstream(chan); 09893 ast_play_and_wait(chan, "vm-goodbye"); 09894 return -1; 09895 } 09896 if (vmu && !skipuser) { 09897 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09898 } 09899 return 0; 09900 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10995 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().
10996 { 10997 struct ast_vm_user svm; 10998 char *context, *box; 10999 AST_DECLARE_APP_ARGS(args, 11000 AST_APP_ARG(mbox); 11001 AST_APP_ARG(options); 11002 ); 11003 static int dep_warning = 0; 11004 11005 if (ast_strlen_zero(data)) { 11006 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 11007 return -1; 11008 } 11009 11010 if (!dep_warning) { 11011 dep_warning = 1; 11012 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 11013 } 11014 11015 box = ast_strdupa(data); 11016 11017 AST_STANDARD_APP_ARGS(args, box); 11018 11019 if (args.options) { 11020 } 11021 11022 if ((context = strchr(args.mbox, '@'))) { 11023 *context = '\0'; 11024 context++; 11025 } 11026 11027 if (find_user(&svm, context, args.mbox)) { 11028 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11029 } else 11030 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11031 11032 return 0; 11033 }
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 9755 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().
09756 { 09757 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09758 return vm_browse_messages_es(chan, vms, vmu); 09759 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09760 return vm_browse_messages_gr(chan, vms, vmu); 09761 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09762 return vm_browse_messages_he(chan, vms, vmu); 09763 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09764 return vm_browse_messages_it(chan, vms, vmu); 09765 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09766 return vm_browse_messages_pt(chan, vms, vmu); 09767 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09768 return vm_browse_messages_vi(chan, vms, vmu); 09769 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09770 return vm_browse_messages_zh(chan, vms, vmu); 09771 } else { /* Default to English syntax */ 09772 return vm_browse_messages_en(chan, vms, vmu); 09773 } 09774 }
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 9594 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().
09595 { 09596 int cmd = 0; 09597 09598 if (vms->lastmsg > -1) { 09599 cmd = play_message(chan, vmu, vms); 09600 } else { 09601 cmd = ast_play_and_wait(chan, "vm-youhave"); 09602 if (!cmd) 09603 cmd = ast_play_and_wait(chan, "vm-no"); 09604 if (!cmd) { 09605 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09606 cmd = ast_play_and_wait(chan, vms->fn); 09607 } 09608 if (!cmd) 09609 cmd = ast_play_and_wait(chan, "vm-messages"); 09610 } 09611 return cmd; 09612 }
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 9648 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().
09649 { 09650 int cmd; 09651 09652 if (vms->lastmsg > -1) { 09653 cmd = play_message(chan, vmu, vms); 09654 } else { 09655 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09656 if (!cmd) 09657 cmd = ast_play_and_wait(chan, "vm-messages"); 09658 if (!cmd) { 09659 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09660 cmd = ast_play_and_wait(chan, vms->fn); 09661 } 09662 } 09663 return cmd; 09664 }
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 9542 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().
09543 { 09544 int cmd = 0; 09545 09546 if (vms->lastmsg > -1) { 09547 cmd = play_message(chan, vmu, vms); 09548 } else { 09549 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09550 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09551 if (!cmd) { 09552 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09553 cmd = ast_play_and_wait(chan, vms->fn); 09554 } 09555 if (!cmd) 09556 cmd = ast_play_and_wait(chan, "vm-messages"); 09557 } else { 09558 if (!cmd) 09559 cmd = ast_play_and_wait(chan, "vm-messages"); 09560 if (!cmd) { 09561 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09562 cmd = ast_play_and_wait(chan, vms->fn); 09563 } 09564 } 09565 } 09566 return cmd; 09567 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9570 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09571 { 09572 int cmd = 0; 09573 09574 if (vms->lastmsg > -1) { 09575 cmd = play_message(chan, vmu, vms); 09576 } else { 09577 if (!strcasecmp(vms->fn, "INBOX")) { 09578 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09579 } else { 09580 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09581 } 09582 } 09583 return cmd; 09584 }
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 9622 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().
09623 { 09624 int cmd; 09625 09626 if (vms->lastmsg > -1) { 09627 cmd = play_message(chan, vmu, vms); 09628 } else { 09629 cmd = ast_play_and_wait(chan, "vm-no"); 09630 if (!cmd) 09631 cmd = ast_play_and_wait(chan, "vm-message"); 09632 if (!cmd) { 09633 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09634 cmd = ast_play_and_wait(chan, vms->fn); 09635 } 09636 } 09637 return cmd; 09638 }
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 9674 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().
09675 { 09676 int cmd; 09677 09678 if (vms->lastmsg > -1) { 09679 cmd = play_message(chan, vmu, vms); 09680 } else { 09681 cmd = ast_play_and_wait(chan, "vm-no"); 09682 if (!cmd) { 09683 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09684 cmd = ast_play_and_wait(chan, vms->fn); 09685 } 09686 if (!cmd) 09687 cmd = ast_play_and_wait(chan, "vm-messages"); 09688 } 09689 return cmd; 09690 }
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 9728 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().
09729 { 09730 int cmd = 0; 09731 09732 if (vms->lastmsg > -1) { 09733 cmd = play_message(chan, vmu, vms); 09734 } else { 09735 cmd = ast_play_and_wait(chan, "vm-no"); 09736 if (!cmd) { 09737 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09738 cmd = ast_play_and_wait(chan, vms->fn); 09739 } 09740 } 09741 return cmd; 09742 }
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 9700 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().
09701 { 09702 int cmd; 09703 09704 if (vms->lastmsg > -1) { 09705 cmd = play_message(chan, vmu, vms); 09706 } else { 09707 cmd = ast_play_and_wait(chan, "vm-you"); 09708 if (!cmd) 09709 cmd = ast_play_and_wait(chan, "vm-haveno"); 09710 if (!cmd) 09711 cmd = ast_play_and_wait(chan, "vm-messages"); 09712 if (!cmd) { 09713 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09714 cmd = ast_play_and_wait(chan, vms->fn); 09715 } 09716 } 09717 return cmd; 09718 }
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_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 (!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 4184 of file app_voicemail.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
04185 { 04186 char *txt; 04187 int txtsize = 0; 04188 04189 txtsize = (strlen(file) + 5)*sizeof(char); 04190 txt = alloca(txtsize); 04191 /* Sprintf here would safe because we alloca'd exactly the right length, 04192 * but trying to eliminate all sprintf's anyhow 04193 */ 04194 if (ast_check_realtime("voicemail_data")) { 04195 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04196 } 04197 snprintf(txt, txtsize, "%s.txt", file); 04198 unlink(txt); 04199 return ast_filedelete(file, NULL); 04200 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10654 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().
10655 { 10656 int res = 0; 10657 char *tmp; 10658 struct leave_vm_options leave_options; 10659 struct ast_flags flags = { 0 }; 10660 char *opts[OPT_ARG_ARRAY_SIZE]; 10661 AST_DECLARE_APP_ARGS(args, 10662 AST_APP_ARG(argv0); 10663 AST_APP_ARG(argv1); 10664 ); 10665 10666 memset(&leave_options, 0, sizeof(leave_options)); 10667 10668 if (chan->_state != AST_STATE_UP) 10669 ast_answer(chan); 10670 10671 if (!ast_strlen_zero(data)) { 10672 tmp = ast_strdupa(data); 10673 AST_STANDARD_APP_ARGS(args, tmp); 10674 if (args.argc == 2) { 10675 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10676 return -1; 10677 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10678 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10679 int gain; 10680 10681 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10682 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10683 return -1; 10684 } else { 10685 leave_options.record_gain = (signed char) gain; 10686 } 10687 } 10688 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10689 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10690 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10691 } 10692 } 10693 } else { 10694 char temp[256]; 10695 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10696 if (res < 0) 10697 return res; 10698 if (ast_strlen_zero(temp)) 10699 return 0; 10700 args.argv0 = ast_strdupa(temp); 10701 } 10702 10703 res = leave_voicemail(chan, args.argv0, &leave_options); 10704 if (res == 't') { 10705 ast_play_and_wait(chan, "vm-goodbye"); 10706 res = 0; 10707 } 10708 10709 if (res == OPERATOR_EXIT) { 10710 res = 0; 10711 } 10712 10713 if (res == ERROR_LOCK_PATH) { 10714 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10715 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10716 res = 0; 10717 } 10718 10719 return res; 10720 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9902 of file app_voicemail.c.
References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), advanced_options(), args, ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_inboxcount2(), ast_app_parse_options(), ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_goto_if_exists(), ast_log(), ast_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().
09903 { 09904 /* XXX This is, admittedly, some pretty horrendous code. For some 09905 reason it just seemed a lot easier to do with GOTO's. I feel 09906 like I'm back in my GWBASIC days. XXX */ 09907 int res = -1; 09908 int cmd = 0; 09909 int valid = 0; 09910 char prefixstr[80] =""; 09911 char ext_context[256]=""; 09912 int box; 09913 int useadsi = 0; 09914 int skipuser = 0; 09915 struct vm_state vms; 09916 struct ast_vm_user *vmu = NULL, vmus; 09917 char *context = NULL; 09918 int silentexit = 0; 09919 struct ast_flags flags = { 0 }; 09920 signed char record_gain = 0; 09921 int play_auto = 0; 09922 int play_folder = 0; 09923 int in_urgent = 0; 09924 #ifdef IMAP_STORAGE 09925 int deleted = 0; 09926 #endif 09927 09928 /* Add the vm_state to the active list and keep it active */ 09929 memset(&vms, 0, sizeof(vms)); 09930 09931 vms.lastmsg = -1; 09932 09933 memset(&vmus, 0, sizeof(vmus)); 09934 09935 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09936 if (chan->_state != AST_STATE_UP) { 09937 ast_debug(1, "Before ast_answer\n"); 09938 ast_answer(chan); 09939 } 09940 09941 if (!ast_strlen_zero(data)) { 09942 char *opts[OPT_ARG_ARRAY_SIZE]; 09943 char *parse; 09944 AST_DECLARE_APP_ARGS(args, 09945 AST_APP_ARG(argv0); 09946 AST_APP_ARG(argv1); 09947 ); 09948 09949 parse = ast_strdupa(data); 09950 09951 AST_STANDARD_APP_ARGS(args, parse); 09952 09953 if (args.argc == 2) { 09954 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09955 return -1; 09956 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09957 int gain; 09958 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09959 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09960 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09961 return -1; 09962 } else { 09963 record_gain = (signed char) gain; 09964 } 09965 } else { 09966 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09967 } 09968 } 09969 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09970 play_auto = 1; 09971 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09972 /* See if it is a folder name first */ 09973 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09974 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09975 play_folder = -1; 09976 } 09977 } else { 09978 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09979 } 09980 } else { 09981 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09982 } 09983 if (play_folder > 9 || play_folder < 0) { 09984 ast_log(AST_LOG_WARNING, 09985 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09986 opts[OPT_ARG_PLAYFOLDER]); 09987 play_folder = 0; 09988 } 09989 } 09990 } else { 09991 /* old style options parsing */ 09992 while (*(args.argv0)) { 09993 if (*(args.argv0) == 's') 09994 ast_set_flag(&flags, OPT_SILENT); 09995 else if (*(args.argv0) == 'p') 09996 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 09997 else 09998 break; 09999 (args.argv0)++; 10000 } 10001 10002 } 10003 10004 valid = ast_test_flag(&flags, OPT_SILENT); 10005 10006 if ((context = strchr(args.argv0, '@'))) 10007 *context++ = '\0'; 10008 10009 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 10010 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 10011 else 10012 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 10013 10014 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 10015 skipuser++; 10016 else 10017 valid = 0; 10018 } 10019 10020 if (!valid) 10021 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 10022 10023 ast_debug(1, "After vm_authenticate\n"); 10024 10025 if (vms.username[0] == '*') { 10026 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 10027 10028 /* user entered '*' */ 10029 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10030 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 10031 res = 0; /* prevent hangup */ 10032 goto out; 10033 } 10034 } 10035 10036 if (!res) { 10037 valid = 1; 10038 if (!skipuser) 10039 vmu = &vmus; 10040 } else { 10041 res = 0; 10042 } 10043 10044 /* If ADSI is supported, setup login screen */ 10045 adsi_begin(chan, &useadsi); 10046 10047 ast_test_suite_assert(valid); 10048 if (!valid) { 10049 goto out; 10050 } 10051 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10052 10053 #ifdef IMAP_STORAGE 10054 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10055 pthread_setspecific(ts_vmstate.key, &vms); 10056 10057 vms.interactive = 1; 10058 vms.updated = 1; 10059 if (vmu) 10060 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10061 vmstate_insert(&vms); 10062 init_vm_state(&vms); 10063 #endif 10064 10065 /* Set language from config to override channel language */ 10066 if (!ast_strlen_zero(vmu->language)) 10067 ast_string_field_set(chan, language, vmu->language); 10068 10069 /* Retrieve urgent, old and new message counts */ 10070 ast_debug(1, "Before open_mailbox\n"); 10071 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10072 if (res < 0) 10073 goto out; 10074 vms.oldmessages = vms.lastmsg + 1; 10075 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10076 /* check INBOX */ 10077 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10078 if (res < 0) 10079 goto out; 10080 vms.newmessages = vms.lastmsg + 1; 10081 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10082 /* Start in Urgent */ 10083 in_urgent = 1; 10084 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10085 if (res < 0) 10086 goto out; 10087 vms.urgentmessages = vms.lastmsg + 1; 10088 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10089 10090 /* Select proper mailbox FIRST!! */ 10091 if (play_auto) { 10092 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10093 if (vms.urgentmessages) { 10094 in_urgent = 1; 10095 res = open_mailbox(&vms, vmu, 11); 10096 } else { 10097 in_urgent = 0; 10098 res = open_mailbox(&vms, vmu, play_folder); 10099 } 10100 if (res < 0) 10101 goto out; 10102 10103 /* If there are no new messages, inform the user and hangup */ 10104 if (vms.lastmsg == -1) { 10105 in_urgent = 0; 10106 cmd = vm_browse_messages(chan, &vms, vmu); 10107 res = 0; 10108 goto out; 10109 } 10110 } else { 10111 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10112 /* If we only have old messages start here */ 10113 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10114 in_urgent = 0; 10115 play_folder = 1; 10116 if (res < 0) 10117 goto out; 10118 } else if (!vms.urgentmessages && vms.newmessages) { 10119 /* If we have new messages but none are urgent */ 10120 in_urgent = 0; 10121 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10122 if (res < 0) 10123 goto out; 10124 } 10125 } 10126 10127 if (useadsi) 10128 adsi_status(chan, &vms); 10129 res = 0; 10130 10131 /* Check to see if this is a new user */ 10132 if (!strcasecmp(vmu->mailbox, vmu->password) && 10133 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10134 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10135 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10136 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10137 if ((cmd == 't') || (cmd == '#')) { 10138 /* Timeout */ 10139 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10140 res = 0; 10141 goto out; 10142 } else if (cmd < 0) { 10143 /* Hangup */ 10144 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10145 res = -1; 10146 goto out; 10147 } 10148 } 10149 #ifdef IMAP_STORAGE 10150 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10151 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10152 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10153 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10154 } 10155 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10156 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10157 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10158 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10159 } 10160 #endif 10161 10162 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10163 if (play_auto) { 10164 cmd = '1'; 10165 } else { 10166 cmd = vm_intro(chan, vmu, &vms); 10167 } 10168 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10169 10170 vms.repeats = 0; 10171 vms.starting = 1; 10172 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10173 /* Run main menu */ 10174 switch (cmd) { 10175 case '1': /* First message */ 10176 vms.curmsg = 0; 10177 /* Fall through */ 10178 case '5': /* Play current message */ 10179 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10180 cmd = vm_browse_messages(chan, &vms, vmu); 10181 break; 10182 case '2': /* Change folders */ 10183 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10184 if (useadsi) 10185 adsi_folders(chan, 0, "Change to folder..."); 10186 10187 cmd = get_folder2(chan, "vm-changeto", 0); 10188 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10189 if (cmd == '#') { 10190 cmd = 0; 10191 } else if (cmd > 0) { 10192 cmd = cmd - '0'; 10193 res = close_mailbox(&vms, vmu); 10194 if (res == ERROR_LOCK_PATH) 10195 goto out; 10196 /* If folder is not urgent, set in_urgent to zero! */ 10197 if (cmd != 11) in_urgent = 0; 10198 res = open_mailbox(&vms, vmu, cmd); 10199 if (res < 0) 10200 goto out; 10201 play_folder = cmd; 10202 cmd = 0; 10203 } 10204 if (useadsi) 10205 adsi_status2(chan, &vms); 10206 10207 if (!cmd) { 10208 cmd = vm_play_folder_name(chan, vms.vmbox); 10209 } 10210 10211 vms.starting = 1; 10212 vms.curmsg = 0; 10213 break; 10214 case '3': /* Advanced options */ 10215 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10216 cmd = 0; 10217 vms.repeats = 0; 10218 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10219 switch (cmd) { 10220 case '1': /* Reply */ 10221 if (vms.lastmsg > -1 && !vms.starting) { 10222 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10223 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10224 res = cmd; 10225 goto out; 10226 } 10227 } else { 10228 cmd = ast_play_and_wait(chan, "vm-sorry"); 10229 } 10230 cmd = 't'; 10231 break; 10232 case '2': /* Callback */ 10233 if (!vms.starting) 10234 ast_verb(3, "Callback Requested\n"); 10235 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10236 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10237 if (cmd == 9) { 10238 silentexit = 1; 10239 goto out; 10240 } else if (cmd == ERROR_LOCK_PATH) { 10241 res = cmd; 10242 goto out; 10243 } 10244 } else { 10245 cmd = ast_play_and_wait(chan, "vm-sorry"); 10246 } 10247 cmd = 't'; 10248 break; 10249 case '3': /* Envelope */ 10250 if (vms.lastmsg > -1 && !vms.starting) { 10251 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10252 if (cmd == ERROR_LOCK_PATH) { 10253 res = cmd; 10254 goto out; 10255 } 10256 } else { 10257 cmd = ast_play_and_wait(chan, "vm-sorry"); 10258 } 10259 cmd = 't'; 10260 break; 10261 case '4': /* Dialout */ 10262 if (!ast_strlen_zero(vmu->dialout)) { 10263 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10264 if (cmd == 9) { 10265 silentexit = 1; 10266 goto out; 10267 } 10268 } else { 10269 cmd = ast_play_and_wait(chan, "vm-sorry"); 10270 } 10271 cmd = 't'; 10272 break; 10273 10274 case '5': /* Leave VoiceMail */ 10275 if (ast_test_flag(vmu, VM_SVMAIL)) { 10276 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10277 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10278 res = cmd; 10279 goto out; 10280 } 10281 } else { 10282 cmd = ast_play_and_wait(chan, "vm-sorry"); 10283 } 10284 cmd = 't'; 10285 break; 10286 10287 case '*': /* Return to main menu */ 10288 cmd = 't'; 10289 break; 10290 10291 default: 10292 cmd = 0; 10293 if (!vms.starting) { 10294 cmd = ast_play_and_wait(chan, "vm-toreply"); 10295 } 10296 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10297 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10298 } 10299 if (!cmd && !vms.starting) { 10300 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10301 } 10302 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10303 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10304 } 10305 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10306 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10307 } 10308 if (!cmd) { 10309 cmd = ast_play_and_wait(chan, "vm-starmain"); 10310 } 10311 if (!cmd) { 10312 cmd = ast_waitfordigit(chan, 6000); 10313 } 10314 if (!cmd) { 10315 vms.repeats++; 10316 } 10317 if (vms.repeats > 3) { 10318 cmd = 't'; 10319 } 10320 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10321 } 10322 } 10323 if (cmd == 't') { 10324 cmd = 0; 10325 vms.repeats = 0; 10326 } 10327 break; 10328 case '4': /* Go to the previous message */ 10329 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10330 if (vms.curmsg > 0) { 10331 vms.curmsg--; 10332 cmd = play_message(chan, vmu, &vms); 10333 } else { 10334 /* Check if we were listening to new 10335 messages. If so, go to Urgent messages 10336 instead of saying "no more messages" 10337 */ 10338 if (in_urgent == 0 && vms.urgentmessages > 0) { 10339 /* Check for Urgent messages */ 10340 in_urgent = 1; 10341 res = close_mailbox(&vms, vmu); 10342 if (res == ERROR_LOCK_PATH) 10343 goto out; 10344 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10345 if (res < 0) 10346 goto out; 10347 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10348 vms.curmsg = vms.lastmsg; 10349 if (vms.lastmsg < 0) { 10350 cmd = ast_play_and_wait(chan, "vm-nomore"); 10351 } 10352 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10353 vms.curmsg = vms.lastmsg; 10354 cmd = play_message(chan, vmu, &vms); 10355 } else { 10356 cmd = ast_play_and_wait(chan, "vm-nomore"); 10357 } 10358 } 10359 break; 10360 case '6': /* Go to the next message */ 10361 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10362 if (vms.curmsg < vms.lastmsg) { 10363 vms.curmsg++; 10364 cmd = play_message(chan, vmu, &vms); 10365 } else { 10366 if (in_urgent && vms.newmessages > 0) { 10367 /* Check if we were listening to urgent 10368 * messages. If so, go to regular new messages 10369 * instead of saying "no more messages" 10370 */ 10371 in_urgent = 0; 10372 res = close_mailbox(&vms, vmu); 10373 if (res == ERROR_LOCK_PATH) 10374 goto out; 10375 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10376 if (res < 0) 10377 goto out; 10378 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10379 vms.curmsg = -1; 10380 if (vms.lastmsg < 0) { 10381 cmd = ast_play_and_wait(chan, "vm-nomore"); 10382 } 10383 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10384 vms.curmsg = 0; 10385 cmd = play_message(chan, vmu, &vms); 10386 } else { 10387 cmd = ast_play_and_wait(chan, "vm-nomore"); 10388 } 10389 } 10390 break; 10391 case '7': /* Delete the current message */ 10392 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10393 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10394 if (useadsi) 10395 adsi_delete(chan, &vms); 10396 if (vms.deleted[vms.curmsg]) { 10397 if (play_folder == 0) { 10398 if (in_urgent) { 10399 vms.urgentmessages--; 10400 } else { 10401 vms.newmessages--; 10402 } 10403 } 10404 else if (play_folder == 1) 10405 vms.oldmessages--; 10406 cmd = ast_play_and_wait(chan, "vm-deleted"); 10407 } else { 10408 if (play_folder == 0) { 10409 if (in_urgent) { 10410 vms.urgentmessages++; 10411 } else { 10412 vms.newmessages++; 10413 } 10414 } 10415 else if (play_folder == 1) 10416 vms.oldmessages++; 10417 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10418 } 10419 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10420 if (vms.curmsg < vms.lastmsg) { 10421 vms.curmsg++; 10422 cmd = play_message(chan, vmu, &vms); 10423 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10424 vms.curmsg = 0; 10425 cmd = play_message(chan, vmu, &vms); 10426 } else { 10427 /* Check if we were listening to urgent 10428 messages. If so, go to regular new messages 10429 instead of saying "no more messages" 10430 */ 10431 if (in_urgent == 1) { 10432 /* Check for new messages */ 10433 in_urgent = 0; 10434 res = close_mailbox(&vms, vmu); 10435 if (res == ERROR_LOCK_PATH) 10436 goto out; 10437 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10438 if (res < 0) 10439 goto out; 10440 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10441 vms.curmsg = -1; 10442 if (vms.lastmsg < 0) { 10443 cmd = ast_play_and_wait(chan, "vm-nomore"); 10444 } 10445 } else { 10446 cmd = ast_play_and_wait(chan, "vm-nomore"); 10447 } 10448 } 10449 } 10450 } else /* Delete not valid if we haven't selected a message */ 10451 cmd = 0; 10452 #ifdef IMAP_STORAGE 10453 deleted = 1; 10454 #endif 10455 break; 10456 10457 case '8': /* Forward the current message */ 10458 if (vms.lastmsg > -1) { 10459 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10460 if (cmd == ERROR_LOCK_PATH) { 10461 res = cmd; 10462 goto out; 10463 } 10464 } else { 10465 /* Check if we were listening to urgent 10466 messages. If so, go to regular new messages 10467 instead of saying "no more messages" 10468 */ 10469 if (in_urgent == 1 && vms.newmessages > 0) { 10470 /* Check for new messages */ 10471 in_urgent = 0; 10472 res = close_mailbox(&vms, vmu); 10473 if (res == ERROR_LOCK_PATH) 10474 goto out; 10475 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10476 if (res < 0) 10477 goto out; 10478 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10479 vms.curmsg = -1; 10480 if (vms.lastmsg < 0) { 10481 cmd = ast_play_and_wait(chan, "vm-nomore"); 10482 } 10483 } else { 10484 cmd = ast_play_and_wait(chan, "vm-nomore"); 10485 } 10486 } 10487 break; 10488 case '9': /* Save message to folder */ 10489 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10490 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10491 /* No message selected */ 10492 cmd = 0; 10493 break; 10494 } 10495 if (useadsi) 10496 adsi_folders(chan, 1, "Save to folder..."); 10497 cmd = get_folder2(chan, "vm-savefolder", 1); 10498 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10499 box = 0; /* Shut up compiler */ 10500 if (cmd == '#') { 10501 cmd = 0; 10502 break; 10503 } else if (cmd > 0) { 10504 box = cmd = cmd - '0'; 10505 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10506 if (cmd == ERROR_LOCK_PATH) { 10507 res = cmd; 10508 goto out; 10509 #ifndef IMAP_STORAGE 10510 } else if (!cmd) { 10511 vms.deleted[vms.curmsg] = 1; 10512 #endif 10513 } else { 10514 vms.deleted[vms.curmsg] = 0; 10515 vms.heard[vms.curmsg] = 0; 10516 } 10517 } 10518 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10519 if (useadsi) 10520 adsi_message(chan, &vms); 10521 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10522 if (!cmd) { 10523 cmd = ast_play_and_wait(chan, "vm-message"); 10524 if (!cmd) 10525 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10526 if (!cmd) 10527 cmd = ast_play_and_wait(chan, "vm-savedto"); 10528 if (!cmd) 10529 cmd = vm_play_folder_name(chan, vms.fn); 10530 } else { 10531 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10532 } 10533 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10534 if (vms.curmsg < vms.lastmsg) { 10535 vms.curmsg++; 10536 cmd = play_message(chan, vmu, &vms); 10537 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10538 vms.curmsg = 0; 10539 cmd = play_message(chan, vmu, &vms); 10540 } else { 10541 /* Check if we were listening to urgent 10542 messages. If so, go to regular new messages 10543 instead of saying "no more messages" 10544 */ 10545 if (in_urgent == 1 && vms.newmessages > 0) { 10546 /* Check for new messages */ 10547 in_urgent = 0; 10548 res = close_mailbox(&vms, vmu); 10549 if (res == ERROR_LOCK_PATH) 10550 goto out; 10551 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10552 if (res < 0) 10553 goto out; 10554 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10555 vms.curmsg = -1; 10556 if (vms.lastmsg < 0) { 10557 cmd = ast_play_and_wait(chan, "vm-nomore"); 10558 } 10559 } else { 10560 cmd = ast_play_and_wait(chan, "vm-nomore"); 10561 } 10562 } 10563 } 10564 break; 10565 case '*': /* Help */ 10566 if (!vms.starting) { 10567 cmd = ast_play_and_wait(chan, "vm-onefor"); 10568 if (!strncasecmp(chan->language, "he", 2)) { 10569 cmd = ast_play_and_wait(chan, "vm-for"); 10570 } 10571 if (!cmd) 10572 cmd = vm_play_folder_name(chan, vms.vmbox); 10573 if (!cmd) 10574 cmd = ast_play_and_wait(chan, "vm-opts"); 10575 if (!cmd) 10576 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10577 } else 10578 cmd = 0; 10579 break; 10580 case '0': /* Mailbox options */ 10581 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10582 if (useadsi) 10583 adsi_status(chan, &vms); 10584 break; 10585 default: /* Nothing */ 10586 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10587 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10588 break; 10589 } 10590 } 10591 if ((cmd == 't') || (cmd == '#')) { 10592 /* Timeout */ 10593 res = 0; 10594 } else { 10595 /* Hangup */ 10596 res = -1; 10597 } 10598 10599 out: 10600 if (res > -1) { 10601 ast_stopstream(chan); 10602 adsi_goodbye(chan); 10603 if (valid && res != OPERATOR_EXIT) { 10604 if (silentexit) 10605 res = ast_play_and_wait(chan, "vm-dialout"); 10606 else 10607 res = ast_play_and_wait(chan, "vm-goodbye"); 10608 } 10609 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10610 res = 0; 10611 } 10612 if (useadsi) 10613 ast_adsi_unload_session(chan); 10614 } 10615 if (vmu) 10616 close_mailbox(&vms, vmu); 10617 if (valid) { 10618 int new = 0, old = 0, urgent = 0; 10619 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10620 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10621 /* Urgent flag not passwd to externnotify here */ 10622 run_externnotify(vmu->context, vmu->mailbox, NULL); 10623 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10624 queue_mwi_event(ext_context, urgent, new, old); 10625 } 10626 #ifdef IMAP_STORAGE 10627 /* expunge message - use UID Expunge if supported on IMAP server*/ 10628 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10629 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10630 ast_mutex_lock(&vms.lock); 10631 #ifdef HAVE_IMAP_TK2006 10632 if (LEVELUIDPLUS (vms.mailstream)) { 10633 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10634 } else 10635 #endif 10636 mail_expunge(vms.mailstream); 10637 ast_mutex_unlock(&vms.lock); 10638 } 10639 /* before we delete the state, we should copy pertinent info 10640 * back to the persistent model */ 10641 if (vmu) { 10642 vmstate_delete(&vms); 10643 } 10644 #endif 10645 if (vmu) 10646 free_user(vmu); 10647 10648 #ifdef IMAP_STORAGE 10649 pthread_setspecific(ts_vmstate.key, NULL); 10650 #endif 10651 return res; 10652 }
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 6862 of file app_voicemail.c.
References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load, ast_config_text_file_save(), ast_filecopy(), ast_filerename(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_stream_and_wait(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), CONFIG_FLAG_NOCACHE, CONFIG_STATUS_FILEINVALID, copy(), INTRO, make_file(), ast_vm_user::maxsecs, maxsilence, play_record_review(), silencethreshold, vm_pls_try_again, and vm_prepend_timeout.
Referenced by forward_message().
06864 { 06865 int cmd = 0; 06866 int retries = 0, prepend_duration = 0, already_recorded = 0; 06867 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06868 char textfile[PATH_MAX]; 06869 struct ast_config *msg_cfg; 06870 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06871 #ifndef IMAP_STORAGE 06872 signed char zero_gain = 0; 06873 #endif 06874 const char *duration_str; 06875 06876 /* Must always populate duration correctly */ 06877 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06878 strcpy(textfile, msgfile); 06879 strcpy(backup, msgfile); 06880 strcpy(backup_textfile, msgfile); 06881 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06882 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06883 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06884 06885 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06886 *duration = atoi(duration_str); 06887 } else { 06888 *duration = 0; 06889 } 06890 06891 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06892 if (cmd) 06893 retries = 0; 06894 switch (cmd) { 06895 case '1': 06896 06897 #ifdef IMAP_STORAGE 06898 /* Record new intro file */ 06899 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06900 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06901 ast_play_and_wait(chan, INTRO); 06902 ast_play_and_wait(chan, "beep"); 06903 cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06904 if (cmd == -1) { 06905 break; 06906 } 06907 cmd = 't'; 06908 #else 06909 06910 /* prepend a message to the current message, update the metadata and return */ 06911 06912 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06913 strcpy(textfile, msgfile); 06914 strncat(textfile, ".txt", sizeof(textfile) - 1); 06915 *duration = 0; 06916 06917 /* if we can't read the message metadata, stop now */ 06918 if (!msg_cfg) { 06919 cmd = 0; 06920 break; 06921 } 06922 06923 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06924 #ifndef IMAP_STORAGE 06925 if (already_recorded) { 06926 ast_filecopy(backup, msgfile, NULL); 06927 copy(backup_textfile, textfile); 06928 } 06929 else { 06930 ast_filecopy(msgfile, backup, NULL); 06931 copy(textfile, backup_textfile); 06932 } 06933 #endif 06934 already_recorded = 1; 06935 06936 if (record_gain) 06937 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06938 06939 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 06940 06941 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 06942 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 06943 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 06944 ast_filerename(backup, msgfile, NULL); 06945 } 06946 06947 if (record_gain) 06948 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06949 06950 06951 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06952 *duration = atoi(duration_str); 06953 06954 if (prepend_duration) { 06955 struct ast_category *msg_cat; 06956 /* need enough space for a maximum-length message duration */ 06957 char duration_buf[12]; 06958 06959 *duration += prepend_duration; 06960 msg_cat = ast_category_get(msg_cfg, "message"); 06961 snprintf(duration_buf, 11, "%ld", *duration); 06962 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06963 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06964 } 06965 } 06966 06967 #endif 06968 break; 06969 case '2': 06970 /* NULL out introfile so we know there is no intro! */ 06971 #ifdef IMAP_STORAGE 06972 *vms->introfn = '\0'; 06973 #endif 06974 cmd = 't'; 06975 break; 06976 case '*': 06977 cmd = '*'; 06978 break; 06979 default: 06980 /* If time_out and return to menu, reset already_recorded */ 06981 already_recorded = 0; 06982 06983 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 06984 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06985 if (!cmd) { 06986 cmd = ast_play_and_wait(chan, "vm-starmain"); 06987 /* "press star to return to the main menu" */ 06988 } 06989 if (!cmd) { 06990 cmd = ast_waitfordigit(chan, 6000); 06991 } 06992 if (!cmd) { 06993 retries++; 06994 } 06995 if (retries > 3) { 06996 cmd = '*'; /* Let's cancel this beast */ 06997 } 06998 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 06999 } 07000 } 07001 07002 if (msg_cfg) 07003 ast_config_destroy(msg_cfg); 07004 if (prepend_duration) 07005 *duration = prepend_duration; 07006 07007 if (already_recorded && cmd == -1) { 07008 /* restore original message if prepention cancelled */ 07009 ast_filerename(backup, msgfile, NULL); 07010 rename(backup_textfile, textfile); 07011 } 07012 07013 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 07014 cmd = 0; 07015 return cmd; 07016 }
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 9217 of file app_voicemail.c.
References ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
09218 { 09219 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09220 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09221 } else { /* Default to ENGLISH */ 09222 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09223 } 09224 }
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 9105 of file app_voicemail.c.
References ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_test_flag, ast_waitfordigit(), vm_state::curmsg, vm_state::deleted, vm_state::lastmsg, vm_state::newmessages, vm_state::repeats, vm_state::starting, vm_state::urgentmessages, VM_MESSAGEWRAP, vm_play_folder_name(), and vm_state::vmbox.
Referenced by vm_instructions(), and vm_instructions_zh().
09106 { 09107 int res = 0; 09108 /* Play instructions and wait for new command */ 09109 while (!res) { 09110 if (vms->starting) { 09111 if (vms->lastmsg > -1) { 09112 if (skipadvanced) 09113 res = ast_play_and_wait(chan, "vm-onefor-full"); 09114 else 09115 res = ast_play_and_wait(chan, "vm-onefor"); 09116 if (!res) 09117 res = vm_play_folder_name(chan, vms->vmbox); 09118 } 09119 if (!res) { 09120 if (skipadvanced) 09121 res = ast_play_and_wait(chan, "vm-opts-full"); 09122 else 09123 res = ast_play_and_wait(chan, "vm-opts"); 09124 } 09125 } else { 09126 /* Added for additional help */ 09127 if (skipadvanced) { 09128 res = ast_play_and_wait(chan, "vm-onefor-full"); 09129 if (!res) 09130 res = vm_play_folder_name(chan, vms->vmbox); 09131 res = ast_play_and_wait(chan, "vm-opts-full"); 09132 } 09133 /* Logic: 09134 * If the current message is not the first OR 09135 * if we're listening to the first new message and there are 09136 * also urgent messages, then prompt for navigation to the 09137 * previous message 09138 */ 09139 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09140 res = ast_play_and_wait(chan, "vm-prev"); 09141 } 09142 if (!res && !skipadvanced) 09143 res = ast_play_and_wait(chan, "vm-advopts"); 09144 if (!res) 09145 res = ast_play_and_wait(chan, "vm-repeat"); 09146 /* Logic: 09147 * If we're not listening to the last message OR 09148 * we're listening to the last urgent message and there are 09149 * also new non-urgent messages, then prompt for navigation 09150 * to the next message 09151 */ 09152 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09153 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09154 res = ast_play_and_wait(chan, "vm-next"); 09155 } 09156 if (!res) { 09157 int curmsg_deleted; 09158 #ifdef IMAP_STORAGE 09159 ast_mutex_lock(&vms->lock); 09160 #endif 09161 curmsg_deleted = vms->deleted[vms->curmsg]; 09162 #ifdef IMAP_STORAGE 09163 ast_mutex_unlock(&vms->lock); 09164 #endif 09165 if (!curmsg_deleted) { 09166 res = ast_play_and_wait(chan, "vm-delete"); 09167 } else { 09168 res = ast_play_and_wait(chan, "vm-undelete"); 09169 } 09170 if (!res) { 09171 res = ast_play_and_wait(chan, "vm-toforward"); 09172 } 09173 if (!res) { 09174 res = ast_play_and_wait(chan, "vm-savemessage"); 09175 } 09176 } 09177 } 09178 if (!res) { 09179 res = ast_play_and_wait(chan, "vm-helpexit"); 09180 } 09181 if (!res) 09182 res = ast_waitfordigit(chan, 6000); 09183 if (!res) { 09184 vms->repeats++; 09185 if (vms->repeats > 2) { 09186 res = 't'; 09187 } 09188 } 09189 } 09190 return res; 09191 }
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 9193 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().
09194 { 09195 int res = 0; 09196 /* Play instructions and wait for new command */ 09197 while (!res) { 09198 if (vms->lastmsg > -1) { 09199 res = ast_play_and_wait(chan, "vm-listen"); 09200 if (!res) 09201 res = vm_play_folder_name(chan, vms->vmbox); 09202 if (!res) 09203 res = ast_play_and_wait(chan, "press"); 09204 if (!res) 09205 res = ast_play_and_wait(chan, "digits/1"); 09206 } 09207 if (!res) 09208 res = ast_play_and_wait(chan, "vm-opts"); 09209 if (!res) { 09210 vms->starting = 0; 09211 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09212 } 09213 } 09214 return res; 09215 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 9043 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().
09044 { 09045 char prefile[256]; 09046 09047 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09048 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09049 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09050 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09051 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09052 ast_play_and_wait(chan, "vm-tempgreetactive"); 09053 } 09054 DISPOSE(prefile, -1); 09055 } 09056 09057 /* Play voicemail intro - syntax is different for different languages */ 09058 if (0) { 09059 return 0; 09060 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09061 return vm_intro_cs(chan, vms); 09062 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09063 static int deprecation_warning = 0; 09064 if (deprecation_warning++ % 10 == 0) { 09065 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09066 } 09067 return vm_intro_cs(chan, vms); 09068 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09069 return vm_intro_de(chan, vms); 09070 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09071 return vm_intro_es(chan, vms); 09072 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09073 return vm_intro_fr(chan, vms); 09074 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09075 return vm_intro_gr(chan, vms); 09076 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09077 return vm_intro_he(chan, vms); 09078 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09079 return vm_intro_it(chan, vms); 09080 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09081 return vm_intro_nl(chan, vms); 09082 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09083 return vm_intro_no(chan, vms); 09084 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09085 return vm_intro_pl(chan, vms); 09086 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09087 return vm_intro_pt_BR(chan, vms); 09088 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09089 return vm_intro_pt(chan, vms); 09090 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09091 return vm_intro_multilang(chan, vms, "n"); 09092 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09093 return vm_intro_se(chan, vms); 09094 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09095 return vm_intro_multilang(chan, vms, "n"); 09096 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09097 return vm_intro_vi(chan, vms); 09098 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09099 return vm_intro_zh(chan, vms); 09100 } else { /* Default to ENGLISH */ 09101 return vm_intro_en(chan, vms); 09102 } 09103 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8913 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().
08914 { 08915 int res; 08916 res = ast_play_and_wait(chan, "vm-youhave"); 08917 if (!res) { 08918 if (vms->newmessages) { 08919 if (vms->newmessages == 1) { 08920 res = ast_play_and_wait(chan, "digits/jednu"); 08921 } else { 08922 res = say_and_wait(chan, vms->newmessages, chan->language); 08923 } 08924 if (!res) { 08925 if ((vms->newmessages == 1)) 08926 res = ast_play_and_wait(chan, "vm-novou"); 08927 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08928 res = ast_play_and_wait(chan, "vm-nove"); 08929 if (vms->newmessages > 4) 08930 res = ast_play_and_wait(chan, "vm-novych"); 08931 } 08932 if (vms->oldmessages && !res) 08933 res = ast_play_and_wait(chan, "vm-and"); 08934 else if (!res) { 08935 if ((vms->newmessages == 1)) 08936 res = ast_play_and_wait(chan, "vm-zpravu"); 08937 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08938 res = ast_play_and_wait(chan, "vm-zpravy"); 08939 if (vms->newmessages > 4) 08940 res = ast_play_and_wait(chan, "vm-zprav"); 08941 } 08942 } 08943 if (!res && vms->oldmessages) { 08944 res = say_and_wait(chan, vms->oldmessages, chan->language); 08945 if (!res) { 08946 if ((vms->oldmessages == 1)) 08947 res = ast_play_and_wait(chan, "vm-starou"); 08948 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08949 res = ast_play_and_wait(chan, "vm-stare"); 08950 if (vms->oldmessages > 4) 08951 res = ast_play_and_wait(chan, "vm-starych"); 08952 } 08953 if (!res) { 08954 if ((vms->oldmessages == 1)) 08955 res = ast_play_and_wait(chan, "vm-zpravu"); 08956 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08957 res = ast_play_and_wait(chan, "vm-zpravy"); 08958 if (vms->oldmessages > 4) 08959 res = ast_play_and_wait(chan, "vm-zprav"); 08960 } 08961 } 08962 if (!res) { 08963 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08964 res = ast_play_and_wait(chan, "vm-no"); 08965 if (!res) 08966 res = ast_play_and_wait(chan, "vm-zpravy"); 08967 } 08968 } 08969 } 08970 return res; 08971 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8609 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().
08610 { 08611 /* Introduce messages they have */ 08612 int res; 08613 res = ast_play_and_wait(chan, "vm-youhave"); 08614 if (!res) { 08615 if (vms->newmessages) { 08616 if ((vms->newmessages == 1)) 08617 res = ast_play_and_wait(chan, "digits/1F"); 08618 else 08619 res = say_and_wait(chan, vms->newmessages, chan->language); 08620 if (!res) 08621 res = ast_play_and_wait(chan, "vm-INBOX"); 08622 if (vms->oldmessages && !res) 08623 res = ast_play_and_wait(chan, "vm-and"); 08624 else if (!res) { 08625 if ((vms->newmessages == 1)) 08626 res = ast_play_and_wait(chan, "vm-message"); 08627 else 08628 res = ast_play_and_wait(chan, "vm-messages"); 08629 } 08630 08631 } 08632 if (!res && vms->oldmessages) { 08633 if (vms->oldmessages == 1) 08634 res = ast_play_and_wait(chan, "digits/1F"); 08635 else 08636 res = say_and_wait(chan, vms->oldmessages, chan->language); 08637 if (!res) 08638 res = ast_play_and_wait(chan, "vm-Old"); 08639 if (!res) { 08640 if (vms->oldmessages == 1) 08641 res = ast_play_and_wait(chan, "vm-message"); 08642 else 08643 res = ast_play_and_wait(chan, "vm-messages"); 08644 } 08645 } 08646 if (!res) { 08647 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08648 res = ast_play_and_wait(chan, "vm-no"); 08649 if (!res) 08650 res = ast_play_and_wait(chan, "vm-messages"); 08651 } 08652 } 08653 } 08654 return res; 08655 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8358 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().
08359 { 08360 int res; 08361 08362 /* Introduce messages they have */ 08363 res = ast_play_and_wait(chan, "vm-youhave"); 08364 if (!res) { 08365 if (vms->urgentmessages) { 08366 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08367 if (!res) 08368 res = ast_play_and_wait(chan, "vm-Urgent"); 08369 if ((vms->oldmessages || vms->newmessages) && !res) { 08370 res = ast_play_and_wait(chan, "vm-and"); 08371 } else if (!res) { 08372 if ((vms->urgentmessages == 1)) 08373 res = ast_play_and_wait(chan, "vm-message"); 08374 else 08375 res = ast_play_and_wait(chan, "vm-messages"); 08376 } 08377 } 08378 if (vms->newmessages) { 08379 res = say_and_wait(chan, vms->newmessages, chan->language); 08380 if (!res) 08381 res = ast_play_and_wait(chan, "vm-INBOX"); 08382 if (vms->oldmessages && !res) 08383 res = ast_play_and_wait(chan, "vm-and"); 08384 else if (!res) { 08385 if ((vms->newmessages == 1)) 08386 res = ast_play_and_wait(chan, "vm-message"); 08387 else 08388 res = ast_play_and_wait(chan, "vm-messages"); 08389 } 08390 08391 } 08392 if (!res && vms->oldmessages) { 08393 res = say_and_wait(chan, vms->oldmessages, chan->language); 08394 if (!res) 08395 res = ast_play_and_wait(chan, "vm-Old"); 08396 if (!res) { 08397 if (vms->oldmessages == 1) 08398 res = ast_play_and_wait(chan, "vm-message"); 08399 else 08400 res = ast_play_and_wait(chan, "vm-messages"); 08401 } 08402 } 08403 if (!res) { 08404 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08405 res = ast_play_and_wait(chan, "vm-no"); 08406 if (!res) 08407 res = ast_play_and_wait(chan, "vm-messages"); 08408 } 08409 } 08410 } 08411 return res; 08412 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8658 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().
08659 { 08660 /* Introduce messages they have */ 08661 int res; 08662 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08663 res = ast_play_and_wait(chan, "vm-youhaveno"); 08664 if (!res) 08665 res = ast_play_and_wait(chan, "vm-messages"); 08666 } else { 08667 res = ast_play_and_wait(chan, "vm-youhave"); 08668 } 08669 if (!res) { 08670 if (vms->newmessages) { 08671 if (!res) { 08672 if ((vms->newmessages == 1)) { 08673 res = ast_play_and_wait(chan, "digits/1M"); 08674 if (!res) 08675 res = ast_play_and_wait(chan, "vm-message"); 08676 if (!res) 08677 res = ast_play_and_wait(chan, "vm-INBOXs"); 08678 } else { 08679 res = say_and_wait(chan, vms->newmessages, chan->language); 08680 if (!res) 08681 res = ast_play_and_wait(chan, "vm-messages"); 08682 if (!res) 08683 res = ast_play_and_wait(chan, "vm-INBOX"); 08684 } 08685 } 08686 if (vms->oldmessages && !res) 08687 res = ast_play_and_wait(chan, "vm-and"); 08688 } 08689 if (vms->oldmessages) { 08690 if (!res) { 08691 if (vms->oldmessages == 1) { 08692 res = ast_play_and_wait(chan, "digits/1M"); 08693 if (!res) 08694 res = ast_play_and_wait(chan, "vm-message"); 08695 if (!res) 08696 res = ast_play_and_wait(chan, "vm-Olds"); 08697 } else { 08698 res = say_and_wait(chan, vms->oldmessages, chan->language); 08699 if (!res) 08700 res = ast_play_and_wait(chan, "vm-messages"); 08701 if (!res) 08702 res = ast_play_and_wait(chan, "vm-Old"); 08703 } 08704 } 08705 } 08706 } 08707 return res; 08708 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8756 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().
08757 { 08758 /* Introduce messages they have */ 08759 int res; 08760 res = ast_play_and_wait(chan, "vm-youhave"); 08761 if (!res) { 08762 if (vms->newmessages) { 08763 res = say_and_wait(chan, vms->newmessages, chan->language); 08764 if (!res) 08765 res = ast_play_and_wait(chan, "vm-INBOX"); 08766 if (vms->oldmessages && !res) 08767 res = ast_play_and_wait(chan, "vm-and"); 08768 else if (!res) { 08769 if ((vms->newmessages == 1)) 08770 res = ast_play_and_wait(chan, "vm-message"); 08771 else 08772 res = ast_play_and_wait(chan, "vm-messages"); 08773 } 08774 08775 } 08776 if (!res && vms->oldmessages) { 08777 res = say_and_wait(chan, vms->oldmessages, chan->language); 08778 if (!res) 08779 res = ast_play_and_wait(chan, "vm-Old"); 08780 if (!res) { 08781 if (vms->oldmessages == 1) 08782 res = ast_play_and_wait(chan, "vm-message"); 08783 else 08784 res = ast_play_and_wait(chan, "vm-messages"); 08785 } 08786 } 08787 if (!res) { 08788 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08789 res = ast_play_and_wait(chan, "vm-no"); 08790 if (!res) 08791 res = ast_play_and_wait(chan, "vm-messages"); 08792 } 08793 } 08794 } 08795 return res; 08796 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8157 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().
08158 { 08159 int res = 0; 08160 08161 if (vms->newmessages) { 08162 res = ast_play_and_wait(chan, "vm-youhave"); 08163 if (!res) 08164 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08165 if (!res) { 08166 if ((vms->newmessages == 1)) { 08167 res = ast_play_and_wait(chan, "vm-INBOX"); 08168 if (!res) 08169 res = ast_play_and_wait(chan, "vm-message"); 08170 } else { 08171 res = ast_play_and_wait(chan, "vm-INBOXs"); 08172 if (!res) 08173 res = ast_play_and_wait(chan, "vm-messages"); 08174 } 08175 } 08176 } else if (vms->oldmessages){ 08177 res = ast_play_and_wait(chan, "vm-youhave"); 08178 if (!res) 08179 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08180 if ((vms->oldmessages == 1)){ 08181 res = ast_play_and_wait(chan, "vm-Old"); 08182 if (!res) 08183 res = ast_play_and_wait(chan, "vm-message"); 08184 } else { 08185 res = ast_play_and_wait(chan, "vm-Olds"); 08186 if (!res) 08187 res = ast_play_and_wait(chan, "vm-messages"); 08188 } 08189 } else if (!vms->oldmessages && !vms->newmessages) 08190 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08191 return res; 08192 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8291 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().
08292 { 08293 int res = 0; 08294 08295 /* Introduce messages they have */ 08296 if (!res) { 08297 if ((vms->newmessages) || (vms->oldmessages)) { 08298 res = ast_play_and_wait(chan, "vm-youhave"); 08299 } 08300 /* 08301 * The word "shtei" refers to the number 2 in hebrew when performing a count 08302 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08303 * an element, this is one of them. 08304 */ 08305 if (vms->newmessages) { 08306 if (!res) { 08307 if (vms->newmessages == 1) { 08308 res = ast_play_and_wait(chan, "vm-INBOX1"); 08309 } else { 08310 if (vms->newmessages == 2) { 08311 res = ast_play_and_wait(chan, "vm-shtei"); 08312 } else { 08313 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08314 } 08315 res = ast_play_and_wait(chan, "vm-INBOX"); 08316 } 08317 } 08318 if (vms->oldmessages && !res) { 08319 res = ast_play_and_wait(chan, "vm-and"); 08320 if (vms->oldmessages == 1) { 08321 res = ast_play_and_wait(chan, "vm-Old1"); 08322 } else { 08323 if (vms->oldmessages == 2) { 08324 res = ast_play_and_wait(chan, "vm-shtei"); 08325 } else { 08326 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08327 } 08328 res = ast_play_and_wait(chan, "vm-Old"); 08329 } 08330 } 08331 } 08332 if (!res && vms->oldmessages && !vms->newmessages) { 08333 if (!res) { 08334 if (vms->oldmessages == 1) { 08335 res = ast_play_and_wait(chan, "vm-Old1"); 08336 } else { 08337 if (vms->oldmessages == 2) { 08338 res = ast_play_and_wait(chan, "vm-shtei"); 08339 } else { 08340 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08341 } 08342 res = ast_play_and_wait(chan, "vm-Old"); 08343 } 08344 } 08345 } 08346 if (!res) { 08347 if (!vms->oldmessages && !vms->newmessages) { 08348 if (!res) { 08349 res = ast_play_and_wait(chan, "vm-nomessages"); 08350 } 08351 } 08352 } 08353 } 08354 return res; 08355 }
static int vm_intro_it | ( | 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, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08416 { 08417 /* Introduce messages they have */ 08418 int res; 08419 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08420 res = ast_play_and_wait(chan, "vm-no") || 08421 ast_play_and_wait(chan, "vm-message"); 08422 else 08423 res = ast_play_and_wait(chan, "vm-youhave"); 08424 if (!res && vms->newmessages) { 08425 res = (vms->newmessages == 1) ? 08426 ast_play_and_wait(chan, "digits/un") || 08427 ast_play_and_wait(chan, "vm-nuovo") || 08428 ast_play_and_wait(chan, "vm-message") : 08429 /* 2 or more new messages */ 08430 say_and_wait(chan, vms->newmessages, chan->language) || 08431 ast_play_and_wait(chan, "vm-nuovi") || 08432 ast_play_and_wait(chan, "vm-messages"); 08433 if (!res && vms->oldmessages) 08434 res = ast_play_and_wait(chan, "vm-and"); 08435 } 08436 if (!res && vms->oldmessages) { 08437 res = (vms->oldmessages == 1) ? 08438 ast_play_and_wait(chan, "digits/un") || 08439 ast_play_and_wait(chan, "vm-vecchio") || 08440 ast_play_and_wait(chan, "vm-message") : 08441 /* 2 or more old messages */ 08442 say_and_wait(chan, vms->oldmessages, chan->language) || 08443 ast_play_and_wait(chan, "vm-vecchi") || 08444 ast_play_and_wait(chan, "vm-messages"); 08445 } 08446 return res; 08447 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8251 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().
08252 { 08253 int res; 08254 int lastnum = 0; 08255 08256 res = ast_play_and_wait(chan, "vm-youhave"); 08257 08258 if (!res && vms->newmessages) { 08259 lastnum = vms->newmessages; 08260 08261 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08262 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08263 } 08264 08265 if (!res && vms->oldmessages) { 08266 res = ast_play_and_wait(chan, "vm-and"); 08267 } 08268 } 08269 08270 if (!res && vms->oldmessages) { 08271 lastnum = vms->oldmessages; 08272 08273 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08274 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08275 } 08276 } 08277 08278 if (!res) { 08279 if (lastnum == 0) { 08280 res = ast_play_and_wait(chan, "vm-no"); 08281 } 08282 if (!res) { 08283 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08284 } 08285 } 08286 08287 return res; 08288 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8799 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().
08800 { 08801 /* Introduce messages they have */ 08802 int res; 08803 res = ast_play_and_wait(chan, "vm-youhave"); 08804 if (!res) { 08805 if (vms->newmessages) { 08806 res = say_and_wait(chan, vms->newmessages, chan->language); 08807 if (!res) { 08808 if (vms->newmessages == 1) 08809 res = ast_play_and_wait(chan, "vm-INBOXs"); 08810 else 08811 res = ast_play_and_wait(chan, "vm-INBOX"); 08812 } 08813 if (vms->oldmessages && !res) 08814 res = ast_play_and_wait(chan, "vm-and"); 08815 else if (!res) { 08816 if ((vms->newmessages == 1)) 08817 res = ast_play_and_wait(chan, "vm-message"); 08818 else 08819 res = ast_play_and_wait(chan, "vm-messages"); 08820 } 08821 08822 } 08823 if (!res && vms->oldmessages) { 08824 res = say_and_wait(chan, vms->oldmessages, chan->language); 08825 if (!res) { 08826 if (vms->oldmessages == 1) 08827 res = ast_play_and_wait(chan, "vm-Olds"); 08828 else 08829 res = ast_play_and_wait(chan, "vm-Old"); 08830 } 08831 if (!res) { 08832 if (vms->oldmessages == 1) 08833 res = ast_play_and_wait(chan, "vm-message"); 08834 else 08835 res = ast_play_and_wait(chan, "vm-messages"); 08836 } 08837 } 08838 if (!res) { 08839 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08840 res = ast_play_and_wait(chan, "vm-no"); 08841 if (!res) 08842 res = ast_play_and_wait(chan, "vm-messages"); 08843 } 08844 } 08845 } 08846 return res; 08847 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8565 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().
08566 { 08567 /* Introduce messages they have */ 08568 int res; 08569 08570 res = ast_play_and_wait(chan, "vm-youhave"); 08571 if (res) 08572 return res; 08573 08574 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08575 res = ast_play_and_wait(chan, "vm-no"); 08576 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08577 return res; 08578 } 08579 08580 if (vms->newmessages) { 08581 if ((vms->newmessages == 1)) { 08582 res = ast_play_and_wait(chan, "digits/1"); 08583 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08584 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08585 } else { 08586 res = say_and_wait(chan, vms->newmessages, chan->language); 08587 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08588 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08589 } 08590 if (!res && vms->oldmessages) 08591 res = ast_play_and_wait(chan, "vm-and"); 08592 } 08593 if (!res && vms->oldmessages) { 08594 if (vms->oldmessages == 1) { 08595 res = ast_play_and_wait(chan, "digits/1"); 08596 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08597 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08598 } else { 08599 res = say_and_wait(chan, vms->oldmessages, chan->language); 08600 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08601 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08602 } 08603 } 08604 08605 return res; 08606 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8450 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().
08451 { 08452 /* Introduce messages they have */ 08453 int res; 08454 div_t num; 08455 08456 if (!vms->oldmessages && !vms->newmessages) { 08457 res = ast_play_and_wait(chan, "vm-no"); 08458 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08459 return res; 08460 } else { 08461 res = ast_play_and_wait(chan, "vm-youhave"); 08462 } 08463 08464 if (vms->newmessages) { 08465 num = div(vms->newmessages, 10); 08466 if (vms->newmessages == 1) { 08467 res = ast_play_and_wait(chan, "digits/1-a"); 08468 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08469 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08470 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08471 if (num.rem == 2) { 08472 if (!num.quot) { 08473 res = ast_play_and_wait(chan, "digits/2-ie"); 08474 } else { 08475 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08476 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08477 } 08478 } else { 08479 res = say_and_wait(chan, vms->newmessages, chan->language); 08480 } 08481 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08482 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08483 } else { 08484 res = say_and_wait(chan, vms->newmessages, chan->language); 08485 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08486 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08487 } 08488 if (!res && vms->oldmessages) 08489 res = ast_play_and_wait(chan, "vm-and"); 08490 } 08491 if (!res && vms->oldmessages) { 08492 num = div(vms->oldmessages, 10); 08493 if (vms->oldmessages == 1) { 08494 res = ast_play_and_wait(chan, "digits/1-a"); 08495 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08496 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08497 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08498 if (num.rem == 2) { 08499 if (!num.quot) { 08500 res = ast_play_and_wait(chan, "digits/2-ie"); 08501 } else { 08502 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08503 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08504 } 08505 } else { 08506 res = say_and_wait(chan, vms->oldmessages, chan->language); 08507 } 08508 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08509 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08510 } else { 08511 res = say_and_wait(chan, vms->oldmessages, chan->language); 08512 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08513 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08514 } 08515 } 08516 08517 return res; 08518 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8850 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().
08851 { 08852 /* Introduce messages they have */ 08853 int res; 08854 res = ast_play_and_wait(chan, "vm-youhave"); 08855 if (!res) { 08856 if (vms->newmessages) { 08857 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08858 if (!res) { 08859 if ((vms->newmessages == 1)) { 08860 res = ast_play_and_wait(chan, "vm-message"); 08861 if (!res) 08862 res = ast_play_and_wait(chan, "vm-INBOXs"); 08863 } else { 08864 res = ast_play_and_wait(chan, "vm-messages"); 08865 if (!res) 08866 res = ast_play_and_wait(chan, "vm-INBOX"); 08867 } 08868 } 08869 if (vms->oldmessages && !res) 08870 res = ast_play_and_wait(chan, "vm-and"); 08871 } 08872 if (!res && vms->oldmessages) { 08873 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08874 if (!res) { 08875 if (vms->oldmessages == 1) { 08876 res = ast_play_and_wait(chan, "vm-message"); 08877 if (!res) 08878 res = ast_play_and_wait(chan, "vm-Olds"); 08879 } else { 08880 res = ast_play_and_wait(chan, "vm-messages"); 08881 if (!res) 08882 res = ast_play_and_wait(chan, "vm-Old"); 08883 } 08884 } 08885 } 08886 if (!res) { 08887 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08888 res = ast_play_and_wait(chan, "vm-no"); 08889 if (!res) 08890 res = ast_play_and_wait(chan, "vm-messages"); 08891 } 08892 } 08893 } 08894 return res; 08895 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8711 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().
08711 { 08712 /* Introduce messages they have */ 08713 int res; 08714 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08715 res = ast_play_and_wait(chan, "vm-nomessages"); 08716 return res; 08717 } else { 08718 res = ast_play_and_wait(chan, "vm-youhave"); 08719 } 08720 if (vms->newmessages) { 08721 if (!res) 08722 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08723 if ((vms->newmessages == 1)) { 08724 if (!res) 08725 res = ast_play_and_wait(chan, "vm-message"); 08726 if (!res) 08727 res = ast_play_and_wait(chan, "vm-INBOXs"); 08728 } else { 08729 if (!res) 08730 res = ast_play_and_wait(chan, "vm-messages"); 08731 if (!res) 08732 res = ast_play_and_wait(chan, "vm-INBOX"); 08733 } 08734 if (vms->oldmessages && !res) 08735 res = ast_play_and_wait(chan, "vm-and"); 08736 } 08737 if (vms->oldmessages) { 08738 if (!res) 08739 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08740 if (vms->oldmessages == 1) { 08741 if (!res) 08742 res = ast_play_and_wait(chan, "vm-message"); 08743 if (!res) 08744 res = ast_play_and_wait(chan, "vm-Olds"); 08745 } else { 08746 if (!res) 08747 res = ast_play_and_wait(chan, "vm-messages"); 08748 if (!res) 08749 res = ast_play_and_wait(chan, "vm-Old"); 08750 } 08751 } 08752 return res; 08753 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8521 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().
08522 { 08523 /* Introduce messages they have */ 08524 int res; 08525 08526 res = ast_play_and_wait(chan, "vm-youhave"); 08527 if (res) 08528 return res; 08529 08530 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08531 res = ast_play_and_wait(chan, "vm-no"); 08532 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08533 return res; 08534 } 08535 08536 if (vms->newmessages) { 08537 if ((vms->newmessages == 1)) { 08538 res = ast_play_and_wait(chan, "digits/ett"); 08539 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08540 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08541 } else { 08542 res = say_and_wait(chan, vms->newmessages, chan->language); 08543 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08544 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08545 } 08546 if (!res && vms->oldmessages) 08547 res = ast_play_and_wait(chan, "vm-and"); 08548 } 08549 if (!res && vms->oldmessages) { 08550 if (vms->oldmessages == 1) { 08551 res = ast_play_and_wait(chan, "digits/ett"); 08552 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08553 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08554 } else { 08555 res = say_and_wait(chan, vms->oldmessages, chan->language); 08556 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08557 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08558 } 08559 } 08560 08561 return res; 08562 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 9013 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().
09014 { 09015 int res; 09016 09017 /* Introduce messages they have */ 09018 res = ast_play_and_wait(chan, "vm-youhave"); 09019 if (!res) { 09020 if (vms->newmessages) { 09021 res = say_and_wait(chan, vms->newmessages, chan->language); 09022 if (!res) 09023 res = ast_play_and_wait(chan, "vm-INBOX"); 09024 if (vms->oldmessages && !res) 09025 res = ast_play_and_wait(chan, "vm-and"); 09026 } 09027 if (!res && vms->oldmessages) { 09028 res = say_and_wait(chan, vms->oldmessages, chan->language); 09029 if (!res) 09030 res = ast_play_and_wait(chan, "vm-Old"); 09031 } 09032 if (!res) { 09033 if (!vms->oldmessages && !vms->newmessages) { 09034 res = ast_play_and_wait(chan, "vm-no"); 09035 if (!res) 09036 res = ast_play_and_wait(chan, "vm-message"); 09037 } 09038 } 09039 } 09040 return res; 09041 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8974 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().
08975 { 08976 int res; 08977 /* Introduce messages they have */ 08978 res = ast_play_and_wait(chan, "vm-you"); 08979 08980 if (!res && vms->newmessages) { 08981 res = ast_play_and_wait(chan, "vm-have"); 08982 if (!res) 08983 res = say_and_wait(chan, vms->newmessages, chan->language); 08984 if (!res) 08985 res = ast_play_and_wait(chan, "vm-tong"); 08986 if (!res) 08987 res = ast_play_and_wait(chan, "vm-INBOX"); 08988 if (vms->oldmessages && !res) 08989 res = ast_play_and_wait(chan, "vm-and"); 08990 else if (!res) 08991 res = ast_play_and_wait(chan, "vm-messages"); 08992 } 08993 if (!res && vms->oldmessages) { 08994 res = ast_play_and_wait(chan, "vm-have"); 08995 if (!res) 08996 res = say_and_wait(chan, vms->oldmessages, chan->language); 08997 if (!res) 08998 res = ast_play_and_wait(chan, "vm-tong"); 08999 if (!res) 09000 res = ast_play_and_wait(chan, "vm-Old"); 09001 if (!res) 09002 res = ast_play_and_wait(chan, "vm-messages"); 09003 } 09004 if (!res && !vms->oldmessages && !vms->newmessages) { 09005 res = ast_play_and_wait(chan, "vm-haveno"); 09006 if (!res) 09007 res = ast_play_and_wait(chan, "vm-messages"); 09008 } 09009 return res; 09010 }
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 3259 of file app_voicemail.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
03260 { 03261 switch (ast_lock_path(path)) { 03262 case AST_LOCK_TIMEOUT: 03263 return -1; 03264 default: 03265 return 0; 03266 } 03267 }
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 9227 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().
09228 { 09229 int cmd = 0; 09230 int duration = 0; 09231 int tries = 0; 09232 char newpassword[80] = ""; 09233 char newpassword2[80] = ""; 09234 char prefile[PATH_MAX] = ""; 09235 unsigned char buf[256]; 09236 int bytes = 0; 09237 09238 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09239 if (ast_adsi_available(chan)) { 09240 bytes += adsi_logo(buf + bytes); 09241 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09242 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09243 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09244 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09245 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09246 } 09247 09248 /* If forcename is set, have the user record their name */ 09249 if (ast_test_flag(vmu, VM_FORCENAME)) { 09250 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09251 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09252 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09253 if (cmd < 0 || cmd == 't' || cmd == '#') 09254 return cmd; 09255 } 09256 } 09257 09258 /* If forcegreetings is set, have the user record their greetings */ 09259 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09260 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09261 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09262 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09263 if (cmd < 0 || cmd == 't' || cmd == '#') 09264 return cmd; 09265 } 09266 09267 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09268 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09269 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09270 if (cmd < 0 || cmd == 't' || cmd == '#') 09271 return cmd; 09272 } 09273 } 09274 09275 /* 09276 * Change the password last since new users will be able to skip over any steps this one comes before 09277 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09278 */ 09279 for (;;) { 09280 newpassword[1] = '\0'; 09281 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09282 if (cmd == '#') 09283 newpassword[0] = '\0'; 09284 if (cmd < 0 || cmd == 't' || cmd == '#') 09285 return cmd; 09286 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09287 if (cmd < 0 || cmd == 't' || cmd == '#') 09288 return cmd; 09289 cmd = check_password(vmu, newpassword); /* perform password validation */ 09290 if (cmd != 0) { 09291 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09292 cmd = ast_play_and_wait(chan, vm_invalid_password); 09293 } else { 09294 newpassword2[1] = '\0'; 09295 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09296 if (cmd == '#') 09297 newpassword2[0] = '\0'; 09298 if (cmd < 0 || cmd == 't' || cmd == '#') 09299 return cmd; 09300 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09301 if (cmd < 0 || cmd == 't' || cmd == '#') 09302 return cmd; 09303 if (!strcmp(newpassword, newpassword2)) 09304 break; 09305 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09306 cmd = ast_play_and_wait(chan, vm_mismatch); 09307 } 09308 if (++tries == 3) 09309 return -1; 09310 if (cmd != 0) { 09311 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09312 } 09313 } 09314 if (pwdchange & PWDCHANGE_INTERNAL) 09315 vm_change_password(vmu, newpassword); 09316 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09317 vm_change_password_shell(vmu, newpassword); 09318 09319 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09320 cmd = ast_play_and_wait(chan, vm_passchanged); 09321 09322 return cmd; 09323 }
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 9325 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().
09326 { 09327 int cmd = 0; 09328 int retries = 0; 09329 int duration = 0; 09330 char newpassword[80] = ""; 09331 char newpassword2[80] = ""; 09332 char prefile[PATH_MAX] = ""; 09333 unsigned char buf[256]; 09334 int bytes = 0; 09335 09336 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09337 if (ast_adsi_available(chan)) { 09338 bytes += adsi_logo(buf + bytes); 09339 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09340 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09341 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09342 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09343 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09344 } 09345 while ((cmd >= 0) && (cmd != 't')) { 09346 if (cmd) 09347 retries = 0; 09348 switch (cmd) { 09349 case '1': /* Record your unavailable message */ 09350 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09351 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09352 break; 09353 case '2': /* Record your busy message */ 09354 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09355 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09356 break; 09357 case '3': /* Record greeting */ 09358 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09359 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09360 break; 09361 case '4': /* manage the temporary greeting */ 09362 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09363 break; 09364 case '5': /* change password */ 09365 if (vmu->password[0] == '-') { 09366 cmd = ast_play_and_wait(chan, "vm-no"); 09367 break; 09368 } 09369 newpassword[1] = '\0'; 09370 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09371 if (cmd == '#') 09372 newpassword[0] = '\0'; 09373 else { 09374 if (cmd < 0) 09375 break; 09376 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09377 break; 09378 } 09379 } 09380 cmd = check_password(vmu, newpassword); /* perform password validation */ 09381 if (cmd != 0) { 09382 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09383 cmd = ast_play_and_wait(chan, vm_invalid_password); 09384 if (!cmd) { 09385 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09386 } 09387 break; 09388 } 09389 newpassword2[1] = '\0'; 09390 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09391 if (cmd == '#') 09392 newpassword2[0] = '\0'; 09393 else { 09394 if (cmd < 0) 09395 break; 09396 09397 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09398 break; 09399 } 09400 } 09401 if (strcmp(newpassword, newpassword2)) { 09402 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09403 cmd = ast_play_and_wait(chan, vm_mismatch); 09404 if (!cmd) { 09405 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09406 } 09407 break; 09408 } 09409 09410 if (pwdchange & PWDCHANGE_INTERNAL) { 09411 vm_change_password(vmu, newpassword); 09412 } 09413 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09414 vm_change_password_shell(vmu, newpassword); 09415 } 09416 09417 ast_debug(1, "User %s set password to %s of length %d\n", 09418 vms->username, newpassword, (int) strlen(newpassword)); 09419 cmd = ast_play_and_wait(chan, vm_passchanged); 09420 break; 09421 case '*': 09422 cmd = 't'; 09423 break; 09424 default: 09425 cmd = 0; 09426 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09427 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09428 if (ast_fileexists(prefile, NULL, NULL)) { 09429 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09430 } 09431 DISPOSE(prefile, -1); 09432 if (!cmd) { 09433 cmd = ast_play_and_wait(chan, "vm-options"); 09434 } 09435 if (!cmd) { 09436 cmd = ast_waitfordigit(chan, 6000); 09437 } 09438 if (!cmd) { 09439 retries++; 09440 } 09441 if (retries > 3) { 09442 cmd = 't'; 09443 } 09444 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09445 } 09446 } 09447 if (cmd == 't') 09448 cmd = 0; 09449 return cmd; 09450 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 8120 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().
08121 { 08122 int cmd; 08123 08124 if ( !strncasecmp(chan->language, "it", 2) || 08125 !strncasecmp(chan->language, "es", 2) || 08126 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08127 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08128 return cmd ? cmd : ast_play_and_wait(chan, box); 08129 } else if (!strncasecmp(chan->language, "gr", 2)) { 08130 return vm_play_folder_name_gr(chan, box); 08131 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08132 return ast_play_and_wait(chan, box); 08133 } else if (!strncasecmp(chan->language, "pl", 2)) { 08134 return vm_play_folder_name_pl(chan, box); 08135 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08136 return vm_play_folder_name_ua(chan, box); 08137 } else if (!strncasecmp(chan->language, "vi", 2)) { 08138 return ast_play_and_wait(chan, box); 08139 } else { /* Default English */ 08140 cmd = ast_play_and_wait(chan, box); 08141 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08142 } 08143 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8073 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08074 { 08075 int cmd; 08076 char *buf; 08077 08078 buf = alloca(strlen(box) + 2); 08079 strcpy(buf, box); 08080 strcat(buf, "s"); 08081 08082 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08083 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08084 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08085 } else { 08086 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08087 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08088 } 08089 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8091 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08092 { 08093 int cmd; 08094 08095 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08096 if (!strcasecmp(box, "vm-INBOX")) 08097 cmd = ast_play_and_wait(chan, "vm-new-e"); 08098 else 08099 cmd = ast_play_and_wait(chan, "vm-old-e"); 08100 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08101 } else { 08102 cmd = ast_play_and_wait(chan, "vm-messages"); 08103 return cmd ? cmd : ast_play_and_wait(chan, box); 08104 } 08105 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8107 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08108 { 08109 int cmd; 08110 08111 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08112 cmd = ast_play_and_wait(chan, "vm-messages"); 08113 return cmd ? cmd : ast_play_and_wait(chan, box); 08114 } else { 08115 cmd = ast_play_and_wait(chan, box); 08116 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08117 } 08118 }
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 9468 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().
09469 { 09470 int cmd = 0; 09471 int retries = 0; 09472 int duration = 0; 09473 char prefile[PATH_MAX] = ""; 09474 unsigned char buf[256]; 09475 int bytes = 0; 09476 09477 if (ast_adsi_available(chan)) { 09478 bytes += adsi_logo(buf + bytes); 09479 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09480 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09481 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09482 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09483 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09484 } 09485 09486 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09487 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09488 while ((cmd >= 0) && (cmd != 't')) { 09489 if (cmd) 09490 retries = 0; 09491 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09492 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09493 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09494 if (cmd == -1) { 09495 break; 09496 } 09497 cmd = 't'; 09498 } else { 09499 switch (cmd) { 09500 case '1': 09501 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09502 break; 09503 case '2': 09504 DELETE(prefile, -1, prefile, vmu); 09505 ast_play_and_wait(chan, "vm-tempremoved"); 09506 cmd = 't'; 09507 break; 09508 case '*': 09509 cmd = 't'; 09510 break; 09511 default: 09512 cmd = ast_play_and_wait(chan, 09513 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09514 "vm-tempgreeting2" : "vm-tempgreeting"); 09515 if (!cmd) { 09516 cmd = ast_waitfordigit(chan, 6000); 09517 } 09518 if (!cmd) { 09519 retries++; 09520 } 09521 if (retries > 3) { 09522 cmd = 't'; 09523 } 09524 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09525 } 09526 } 09527 DISPOSE(prefile, -1); 09528 } 09529 if (cmd == 't') 09530 cmd = 0; 09531 return cmd; 09532 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11422 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().
11424 { 11425 struct ast_vm_user *user; 11426 11427 AST_LIST_LOCK(&users); 11428 AST_LIST_TRAVERSE(&users, user, list) { 11429 vm_users_data_provider_get_helper(search, data_root, user); 11430 } 11431 AST_LIST_UNLOCK(&users); 11432 11433 return 0; 11434 }
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 11375 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().
11377 { 11378 struct ast_data *data_user, *data_zone; 11379 struct ast_data *data_state; 11380 struct vm_zone *zone = NULL; 11381 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11382 char ext_context[256] = ""; 11383 11384 data_user = ast_data_add_node(data_root, "user"); 11385 if (!data_user) { 11386 return -1; 11387 } 11388 11389 ast_data_add_structure(ast_vm_user, data_user, user); 11390 11391 AST_LIST_LOCK(&zones); 11392 AST_LIST_TRAVERSE(&zones, zone, list) { 11393 if (!strcmp(zone->name, user->zonetag)) { 11394 break; 11395 } 11396 } 11397 AST_LIST_UNLOCK(&zones); 11398 11399 /* state */ 11400 data_state = ast_data_add_node(data_user, "state"); 11401 if (!data_state) { 11402 return -1; 11403 } 11404 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11405 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11406 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11407 ast_data_add_int(data_state, "newmsg", newmsg); 11408 ast_data_add_int(data_state, "oldmsg", oldmsg); 11409 11410 if (zone) { 11411 data_zone = ast_data_add_node(data_user, "zone"); 11412 ast_data_add_structure(vm_zone, data_zone, zone); 11413 } 11414 11415 if (!ast_data_search_match(search, data_user)) { 11416 ast_data_remove_node(data_root, data_user); 11417 } 11418 11419 return 0; 11420 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11059 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().
11060 { 11061 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11062 struct ast_vm_user vmus; 11063 char *options = NULL; 11064 int silent = 0, skipuser = 0; 11065 int res = -1; 11066 11067 if (data) { 11068 s = ast_strdupa(data); 11069 user = strsep(&s, ","); 11070 options = strsep(&s, ","); 11071 if (user) { 11072 s = user; 11073 user = strsep(&s, "@"); 11074 context = strsep(&s, ""); 11075 if (!ast_strlen_zero(user)) 11076 skipuser++; 11077 ast_copy_string(mailbox, user, sizeof(mailbox)); 11078 } 11079 } 11080 11081 if (options) { 11082 silent = (strchr(options, 's')) != NULL; 11083 } 11084 11085 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11086 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11087 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11088 ast_play_and_wait(chan, "auth-thankyou"); 11089 res = 0; 11090 } else if (mailbox[0] == '*') { 11091 /* user entered '*' */ 11092 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11093 res = 0; /* prevent hangup */ 11094 } 11095 } 11096 11097 return res; 11098 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12601 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().
12602 { 12603 char *context; 12604 char *args_copy; 12605 int res; 12606 12607 if (ast_strlen_zero(data)) { 12608 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n"); 12609 return -1; 12610 } 12611 12612 args_copy = ast_strdupa(data); 12613 if ((context = strchr(args_copy, '@'))) { 12614 *context++ = '\0'; 12615 } else { 12616 context = "default"; 12617 } 12618 12619 if ((res = sayname(chan, args_copy, context) < 0)) { 12620 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12621 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12622 if (!res) { 12623 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12624 } 12625 } 12626 12627 return res; 12628 }
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 4416 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().
04417 { 04418 const struct vm_zone *z = NULL; 04419 struct timeval t = ast_tvnow(); 04420 04421 /* Does this user have a timezone specified? */ 04422 if (!ast_strlen_zero(vmu->zonetag)) { 04423 /* Find the zone in the list */ 04424 AST_LIST_LOCK(&zones); 04425 AST_LIST_TRAVERSE(&zones, z, list) { 04426 if (!strcmp(z->name, vmu->zonetag)) 04427 break; 04428 } 04429 AST_LIST_UNLOCK(&zones); 04430 } 04431 ast_localtime(&t, tm, z ? z->timezone : NULL); 04432 return tm; 04433 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7469 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().
07470 { 07471 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07472 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); 07473 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7461 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().
07462 { 07463 int res; 07464 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07465 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07466 return res; 07467 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12568 of file app_voicemail.c.
References ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_destroy(), ast_config_new(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), LOG_ERROR, and var.
Referenced by vm_change_password().
12568 { 12569 struct ast_config *conf; 12570 struct ast_category *cat; 12571 struct ast_variable *var; 12572 int res = -1; 12573 12574 if (!(conf = ast_config_new())) { 12575 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12576 return res; 12577 } 12578 if (!(cat = ast_category_new("general", "", 1))) { 12579 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12580 ast_config_destroy(conf); 12581 return res; 12582 } 12583 if (!(var = ast_variable_new("password", password, ""))) { 12584 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12585 ast_config_destroy(conf); 12586 ast_category_destroy(cat); 12587 return res; 12588 } 12589 ast_category_append(conf, cat); 12590 ast_variable_append(cat, var); 12591 if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12592 res = 0; 12593 } else { 12594 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12595 } 12596 12597 ast_config_destroy(conf); 12598 return res; 12599 }
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } [static] |
Definition at line 13680 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 13680 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 11298 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 11054 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 11436 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().